Why does else behave differently in for/while statements as opposed to if/try statements?

纵饮孤独 提交于 2019-12-07 03:22:46

问题


I have recently stumbled over a seeming inconsistency in Python's way of dealing with else clauses in different compound statements. Since Python is so well designed, I'm sure that there is a good explanation, but I can't think of it.

Consider the following:

if condition:
   do_something()
else:
   do_something_else()

Here, do_something_else() is only executed if 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 no exception occurred.

But in for or while loops, an else clause is always executed, whether the contents of the for/while block have been executed or not.

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

will always print "Iterator is empty!", whether I say some_iterator = [] or some_iterator = [1,2,3]. Same behavior in while-else clauses. It seems to me that else behaves more like finally in these cases. What am I overlooking?


回答1:


Well, it depends how you see it. You can look at the elses like this (excuse the screaming, its the only way to make emphasis in 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 an else to 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()

Same goes for the 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 else in some fundamental way do work exactly the same in all three cases.

But you can also see the else in this way:

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

And then it's not the same anymore, but the else because a sort 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, considering the elif, then this way of seeing it works for if/else as well:

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

Which way you want to look at the else is up to you, but in both ways of viewing, else do have similarities in all three cases.




回答2:


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

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



回答3:


Yes, as Eli mentioned, the else clause is executed only if you don't break. It stops you from implementing code like this:

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

Which is roughly equivalent here, but handy if the conditions for quitting are a bit more complicated (like checking various possible conditions or combinations of conditions).



来源:https://stackoverflow.com/questions/1576537/why-does-else-behave-differently-in-for-while-statements-as-opposed-to-if-try-st

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!