Else statement executing when it shouldnt

T

Thomas Boell

Examples:

# else branch will be executed
i = 0
while i < 5:
i += 1
else:
print('loop is over')


# else branch will be executed
i = 0
while i < 5:
i += 1
if i == 7:
print('i == 7')
break
else:
print('loop is over')


# else branch wont be executed
i = 0
while i < 5:
i += 1
if i == 3:
print('i == 3')
break
else:
print('loop is over')

Huh?! I would have expected all your examples to raise a SyntaxError or
IndentationError. Why don't they? Is 'else' not required to have a
matching 'if'?
 
C

Chris Angelico

Huh?! I would have expected all your examples to raise a SyntaxError or
IndentationError. Why don't they? Is 'else' not required to have a
matching 'if'?

Other things can have else, including 'for' and 'while' loops. :)

ChrisA
 
T

Thomas Boell

Other things can have else, including 'for' and 'while' loops. :)

I must say, that's bound to be confusing for anyone who knows any
language other than Python (or none, even). Syntax like that is "an
accident waiting to happen"...
 
S

Steven D'Aprano

I must say, that's bound to be confusing for anyone who knows any
language other than Python (or none, even). Syntax like that is "an
accident waiting to happen"...

Oh it's even worse than that. I reckon that nearly everyone thinks that
for...else runs the "else" clause if the for loop is empty, at least the
first time they see it. Or for the slow of thinking like me, the first
few dozen times.

# this is wrong, but it looks right
for x in sequence:
do_something_with(x)
else:
print "sequence is empty"


But no, that's not what it does. `for...else` is actually more like this:


# this is right
for x in sequence:
do_something_with(x)
if condition:
break
else:
print "condition was never true"


That's right. The `else` block *unconditionally* executes after the `for`
block. The only way to skip it is to use `break`, which skips all the way
out of the combined for...else statement.

This is a very useful feature, very badly named.
 
R

René KlaÄan

it seems that lot of you are forgeting about this case:

for i in [1,2,3,4,5]:
print i
else:
print('this will be printed also because cycle wasnt broke')

so the one case when else branch is executed is when condition is not
satisfied and the other case is when there is no break executed during the
cycle

On Wed, Jan 23, 2013 at 12:22 AM, Steven D'Aprano <
 
A

alex23

I must say, that's bound to be confusing for anyone who knows any
language other than Python (or none, even).  Syntax like that is "an
accident waiting to happen"...

No, ignorantly expecting every language to conform to every other is
the pending accident.
 
D

Dennis Lee Bieber

it seems that lot of you are forgeting about this case:

for i in [1,2,3,4,5]:
print i
else:
print('this will be printed also because cycle wasnt broke')

so the one case when else branch is executed is when condition is not
satisfied and the other case is when there is no break executed during the
cycle

The short summary is that the "else:" is performed ANY TIME the loop
exits normally... Only an internal "break" will skip the "else:".
 
T

Thomas Boell

No, ignorantly expecting every language to conform to every other is
the pending accident.

Using a keyword that has a well-understood meaning in just about every
other programming language on the planet *and even in English*,
redefining it to mean something completely different, and then making
the syntax look like the original, well-understood meaning -- that's
setting a trap out for users.

The feature isn't bad, it's just very, very badly named.
 
J

Jussi Piitulainen

Thomas said:
Using a keyword that has a well-understood meaning in just about
every other programming language on the planet *and even in
English*, redefining it to mean something completely different, and
then making the syntax look like the original, well-understood
meaning -- that's setting a trap out for users.

The feature isn't bad, it's just very, very badly named.

I believe it would read better - much better - if it was "for/then"
and "while/then" instead of "for/else" and "while/else".

I believe someone didn't want to introduce a new keyword for this,
hence "else".
 
J

Jerry Hill

I believe it would read better - much better - if it was "for/then"
and "while/then" instead of "for/else" and "while/else".

That's always been my opinion too. I'd remember how the construct
worked if it was for/then (and while/then). Since seeing for/else
always makes my brain lock up for a few seconds when I'm reading code,
I don't bother using it.

Jerry
 
F

Frank Millman

I believe it would read better - much better - if it was "for/then"
and "while/then" instead of "for/else" and "while/else".

I believe someone didn't want to introduce a new keyword for this,
hence "else".

There is a scenario, which I use from time to time, where 'else' makes
perfect sense.

You want to loop through an iterable, looking for 'something'. If you
find it, you want to do something and break. If you do not find it, you
want to do something else.

for item in iterable:
if item == 'something':
do_something()
break
else: # item was not found
do_something_else()

Not arguing for or against, just saying it is difficult to find one word
which covers all requirements.

Frank Millman
 

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,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top