Why does another behavior behave differently for while statements, and not for if / try statements?

I recently stumbled upon a seeming inconsistency in Python's way of working with else clauses in different compound statements. Since Python is so well designed, I am sure there is a good explanation, but I cannot think about it.

Consider the following:

if condition: do_something() else: do_something_else() 

Here, do_something_else() is only executed if the condition is false, as expected.

Similarly, in

 try: do_something() except someException: pass: else: do_something_else() finally: cleanup() 

do_something_else() is only executed if an exception occurs.

But for while or while loops, the else condition is always satisfied, regardless of whether the contents of the for/while block or not.

 for i in some_iterator: print(i) else: print("Iterator is empty!") 

will always print β€œThe iterator is empty!” whether I some_iterator = [] or some_iterator = [1,2,3] . Same behavior in while-else . It seems to me that else behaves more like finally in these cases. What am I missing?

+6
python flow-control
source share
3 answers

Well, it depends on how you see it. You can look at elses like this (sorry to shout, its the only way to emphasize the code):

 if condition: do_something() IF THE PREVIOUS CONDITION WAS FALSE: do_something_else() 

Now there is an obvious similarity between if / else and try / except / else if you see the else statement as else for the except statement. Like this.

 try: do_something() IF THERE WAS AN EXCEPTION: pass: IF THE PREVIOUS CONDITION WAS FALSE: do_something_else() finally: cleanup() 

The same applies to else / for:

 IF some_iterator IS NOT EMPTY: i = next(some_iterator) print(i) IF THE PREVIOUS CONDITION WAS FALSE: print("Iterator is empty!") 

So, here we see that the other fundamentally works the same in all three cases.

But you can also see something else:

 try: do_something() except someException: pass: IF NO EXCEPTION: do_something_else() finally: cleanup() 

And then this is not the same, but different, because it is a kind of "if nothing else." You can see for / else in the same way:

 for i in some_iterator: print(i) IF NO MORE ITERATING: print("Iterator is empty!") 

But then again, given elif, then this way of seeing that it works for if / else:

 if condition: do_something() elif otherconditaion: do_anotherthing() IF NO CONDITION WAS TRUE: do_something_else() 

How you want to look at the other is up to you, but in both ways of viewing they still have similarities in all three cases.

+5
source share

The for else executes the else clause if the break statement was not executed for the loop, as described here . For example, this else condition is never evaluated.

 for i in range(1,10): if i % 5 == 0: print i break else: print "nothing divisible by 5" 
+13
source share

Yes, as Eli mentioned, the else clause is only executed if you don't break. This prevents you from implementing the code as follows:

 for i in range(1,10): if i % 5 == 0: print i break if i % 5 != 0: print "nothing divisible by 5" 

This is roughly equivalent here, but convenient if the conditions for termination are a little more complicated (for example, checking various possible conditions or combinations of conditions).

+4
source share

All Articles