Simple if-else question

S

Sandy

Hi all,
A simple and silly if-else question.
I saw some code that has the following structure. My question is why
else is used there though removing else
has the same result. More important, is it not syntactically wrong :-(

for i in xrange(8):
if i < 4:
print i
else:
print i

Cheers,
dksr
 
J

Joel Goldstick

Sandy said:
Hi all,
A simple and silly if-else question.
I saw some code that has the following structure. My question is why
else is used there though removing else
has the same result. More important, is it not syntactically wrong :-(

for i in xrange(8):
if i < 4:
print i
else:
print i

Cheers,
dksr


else needs to be indented like if
 
G

Gary Herron

Sandy said:
Hi all,
A simple and silly if-else question.
I saw some code that has the following structure. My question is why
else is used there though removing else
has the same result. More important, is it not syntactically wrong :-(

for i in xrange(8):
if i < 4:
print i
else:
print i

Cheers,
dksr

See
http://docs.python.org/reference/compound_stmts.html#the-for-statement
for an explanation of the "for" statement, and the meaning of it's
"else" suite.

In this particular instance, the "else" adds nothing, but there are
instances where it does provide a useful functionality.

Gary Herron
 
E

Ethan Furman

Sandy said:
Hi all,
A simple and silly if-else question.
I saw some code that has the following structure. My question is why
else is used there though removing else
has the same result. More important, is it not syntactically wrong :-(

for i in xrange(8):
if i < 4:
print i
else:
print i

Cheers,
dksr

The else is not tied to the if, it is tied to the for. The statements
in a for-else (and while-else, and if-else) only execute if the control
expression becomes False. If you want to avoid executing the else
clause, you have to break out of the loop.

Some examples:

In [1]: for i in xrange(8):
...: if i < 4:
...: print i
...:
0
1
2
3

In [2]: for i in xrange(8):
...: if i < 4:
...: print i
...: else:
...: print i
...:
0
1
2
3
7

In [3]: for i in xrange(8):
...: if i < 4:
...: print i
...: if i == 1:
...: break
...: else:
...: print i
...:
0
1

Hope this helps!

~Ethan~
 
C

Carl Banks

Seehttp://docs.python.org/reference/compound_stmts.html#the-for-statement
for an explanation of the "for" statement, and the meaning of it's
"else" suite.

In this particular instance, the "else" adds nothing, but there are
instances where it does provide a useful functionality.

Hmm, I wonder if Python should emit a warning if an else is used on a
for block with no break inside. I don't think the else can be invoked
in any other way. As a bonus it could catch some cases where people
mistakenly use it thinking it will execute when there are no
iterations.

Carl Banks
 
M

MRAB

Ethan said:
Sandy said:
Hi all,
A simple and silly if-else question.
I saw some code that has the following structure. My question is why
else is used there though removing else
has the same result. More important, is it not syntactically wrong :-(

for i in xrange(8):
if i < 4:
print i
else:
print i

Cheers,
dksr

The else is not tied to the if, it is tied to the for. The statements
in a for-else (and while-else, and if-else) only execute if the control
expression becomes False. If you want to avoid executing the else
clause, you have to break out of the loop.

Some examples:

In [1]: for i in xrange(8):
...: if i < 4:
...: print i
...:
0
1
2
3

In [2]: for i in xrange(8):
...: if i < 4:
...: print i
...: else:
...: print i
...:
0
1
2
3
7

In [3]: for i in xrange(8):
...: if i < 4:
...: print i
...: if i == 1:
...: break
...: else:
...: print i
...:
0
1

Hope this helps!
The example that makes it clearest for me is searching through a list
for a certain item and breaking out of the 'for' loop if I find it. If I
get to the end of the list and still haven't broken out then I haven't
found the item, and that's when the else statement takes effect:

for item in my_list:
if item == desired_item:
print "Found it!"
break
else:
print "It's not in the list"
 
C

Carl Banks

It will execute when there are no iterations. Did you mean to say people
think it will execute *only* when there are no iterations?


No but that's what I should have meant.


Carl Banks
 
J

John Yeung

Hmm, I wonder if Python should emit a warning if an else is
used on a for block with no break inside.  I don't think the
else can be invoked in any other way.  As a bonus it could
catch some cases where people mistakenly use it thinking it
will execute [only] when there are no iterations.

[Edit from Duncan Booth]

I would definitely be in favor of a warning. Yes, people should read
the docs more carefully, and yes, it would cost a certain amount of
annoyance to implement this. But I don't think it would get in
people's way if they do know how to use else, and I think it would cut
down on the number of questions from mystified beginners, some of whom
are much more aggressive than this particular OP about claiming that
Python is broken (when it's actually behaving as designed).

John
 
J

John Yeung

The example that makes it clearest for me is searching
through a list for a certain item and breaking out of
the 'for' loop if I find it. If I get to the end of the
list and still haven't broken out then I haven't found
the item, and that's when the else statement takes effect:

for item in my_list:
     if item == desired_item:
         print "Found it!"
         break
else:
     print "It's not in the list"

To me, this is the quintessential use case and clearest example of the
for-else.

John
 
S

Steven D'Aprano

Hmm, I wonder if Python should emit a warning if an else is used on a
for block with no break inside.  I don't think the else can be invoked
in any other way.  As a bonus it could catch some cases where people
mistakenly use it thinking it will execute [only] when there are no
iterations.

[Edit from Duncan Booth]

I would definitely be in favor of a warning. Yes, people should read
the docs more carefully, and yes, it would cost a certain amount of
annoyance to implement this. But I don't think it would get in people's
way if they do know how to use else,

Of course it would. It would mean that everybody who knows how to use
for...else correctly would have to deal with a totally useless warning.

and I think it would cut down on
the number of questions from mystified beginners, some of whom are much
more aggressive than this particular OP about claiming that Python is
broken (when it's actually behaving as designed).

By raising a warning, you are implying that the behaviour is broken, or
at least suspicious. Warnings mean something needs to be warned against
-- "don't do this". Warnings shouldn't be perfectly legitimate behaviours
on the off-chance that the user is confused. "Warning, are you sure you
want to put the car into reverse? Perhaps you meant neutral?"

What would the warning say?

"Warning, you have used a legitimate Python control structure but you
might be confused by it."

"Warning, did you mean if...else instead of for...else?"

Then we can add a whole lot of extra warnings to protect newbies who
don't read docs (and probably won't read the warnings either) from
themselves:

"Warning, did you mean obj(1) instead of obj[1]?"

"Warning, did you mean def f(object) instead of class f(object)?"

"Warning, did you mean class f(object) instead of def f(object)?"

"Warning, did you mean 2*3 instead of 2**3?"

"Warning, did you mean %s instead of %x?"

"Warning, we think you're helpless and don't know what you want, perhaps
you should be programming in PHP?"



I'm sympathetic to the desire to educate the n00bs, and in fact I've even
suggested similar warnings myself. But I've been convinced that this is
the wrong approach. Certainly the language shouldn't assume the
programmer is confused. If this sort of warning belongs anywhere (and
that's a big if), it belongs in an IDE.
 
T

Terry Reedy

John said:
Hmm, I wonder if Python should emit a warning if an else is
used on a for block with no break inside. I don't think the
else can be invoked in any other way. As a bonus it could
catch some cases where people mistakenly use it thinking it
will execute [only] when there are no iterations.

[Edit from Duncan Booth]

I would definitely be in favor of a warning. Yes, people should read
the docs more carefully, and yes, it would cost a certain amount of
annoyance to implement this. But I don't think it would get in
people's way if they do know how to use else, and I think it would cut
down on the number of questions from mystified beginners, some of whom
are much more aggressive than this particular OP about claiming that
Python is broken (when it's actually behaving as designed).

This sort of warning is appropriate for code checkers like Pylint,
Pychecker, but not for the running interpreter.

tjr
 
D

dksr

It will execute when there are no iterations. Did you mean to say people
think it will execute *only* when there are no iterations?

Yes thats what I thought. for-else looks similar to if-else and in if-
else, else part is executed only when if part is not executed, but in
for-else it has entirely a different job.
Thats somewhat confusing, though it will be clear after playing around
with it.

- dksr
 
I

Iain King

Hmm, I wonder if Python should emit a warning if an else is used on a
for block with no break inside.  I don't think the else can be invoked
in any other way.  As a bonus it could catch some cases where people
mistakenly use it thinking it will execute [only] when there are no
iterations.
[Edit from Duncan Booth]
I would definitely be in favor of a warning.  Yes, people should read
the docs more carefully, and yes, it would cost a certain amount of
annoyance to implement this.  But I don't think it would get in people's
way if they do know how to use else,

Of course it would. It would mean that everybody who knows how to use
for...else correctly would have to deal with a totally useless warning.
and I think it would cut down on
the number of questions from mystified beginners, some of whom are much
more aggressive than this particular OP about claiming that Python is
broken (when it's actually behaving as designed).

By raising a warning, you are implying that the behaviour is broken, or
at least suspicious. Warnings mean something needs to be warned against
-- "don't do this". Warnings shouldn't be perfectly legitimate behaviours
on the off-chance that the user is confused. "Warning, are you sure you
want to put the car into reverse? Perhaps you meant neutral?"

What would the warning say?

"Warning, you have used a legitimate Python control structure but you
might be confused by it."

"Warning, did you mean if...else instead of for...else?"

Then we can add a whole lot of extra warnings to protect newbies who
don't read docs (and probably won't read the warnings either) from
themselves:

"Warning, did you mean obj(1) instead of obj[1]?"

"Warning, did you mean def f(object) instead of class f(object)?"

"Warning, did you mean class f(object) instead of def f(object)?"

"Warning, did you mean 2*3 instead of 2**3?"

"Warning, did you mean %s instead of %x?"

"Warning, we think you're helpless and don't know what you want, perhaps
you should be programming in PHP?"

I'm sympathetic to the desire to educate the n00bs, and in fact I've even
suggested similar warnings myself. But I've been convinced that this is
the wrong approach. Certainly the language shouldn't assume the
programmer is confused. If this sort of warning belongs anywhere (and
that's a big if), it belongs in an IDE.

Read the suggestion again - it's not a warning on the for-else
structure, it's a warning when the for-else doesn't contain a break;
he's theorising that a for-else without a break will always trigger
the else, in which case it's almost certainly an error, and having the
warning is not a bad idea.
However, I assume you can get past the else by raising an exception,
so the idea becomes a little muddled - do you warn when there is no
break and no explicit raise caught outside the loop? What about an
implicit exception? I would guess that code intentionally using an
implicit exception to break out of a for loop is in need of a warning
(and the author in need of the application of a lart), but I'm sure
you could construct a plausible situation where it wouldn't be that
bad...

Anyway, I'm ambivalently on the fence.

Iain
 
C

Carl Banks

Read the suggestion again - it's not a warning on the for-else
structure, it's a warning when the for-else doesn't contain a break;
he's theorising that a for-else without a break will always trigger
the else, in which case it's almost certainly an error, and having the
warning is not a bad idea.

I actually had minor moment of confusion, somehow I was thinking that
if no break appeared in the for-block then the else-block would be
impossible to execute (the opposite of what actually happens). Even
then just kind of throwing the idea out there, wasn't really
advocating it.

Now that I am no longer confused I definitely don't think there should
be a warning.


Carl Banks
 
A

alex23

dksr said:
Yes thats what I thought. for-else looks similar to if-else and in if-
else, else part is executed only when if part is not executed, but in
for-else it has entirely a different job.

If you think of if-else more in terms of the else-branch occurring
when the if-condition is no longer true (as opposed to 'not
executing'), they're a lot more similar in approach than different.
 
S

Sion Arrowsmith

MRAB said:
[ for ... else ]
The example that makes it clearest for me is searching through a list
for a certain item and breaking out of the 'for' loop if I find it. If I
get to the end of the list and still haven't broken out then I haven't
found the item, and that's when the else statement takes effect:

What works for me is thinking about the while ... else construct
and comparing it to if ... else:

if x:
print "x is True"
else:
print "x is False"

while x:
print "x is True"
x -= 1 # or something
# A break here exits the loop with x True
else:
print "x is False"

then the step from while to for is obvious.
 
O

Olof Bjarnason

2009/10/1 Sion Arrowsmith said:
MRAB   said:
[ for ... else ]
The example that makes it clearest for me is searching through a list
for a certain item and breaking out of the 'for' loop if I find it. If I
get to the end of the list and still haven't broken out then I haven't
found the item, and that's when the else statement takes effect:

What works for me is thinking about the while ... else construct
and comparing it to if ... else:

if x:
   print "x is True"
else:
   print "x is False"

while x:
   print "x is True"
   x -= 1 # or something
   # A break here exits the loop with x True
else:
   print "x is False"

then the step from while to for is obvious.

Am I grokking for..else:

for i in range(10):
if fn(i):
break
nobreak: # let 'nobreak' mean 'else'
print('break did not happen')
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top