We all know how to use the else keyword with if:
if x > 0: print 'positive' elif x < 0: print 'negative' else: print 'zero'
However, in Python, there are several other applications that are unknown to most programmers, else.
')
for ... else
I bet you don't know what else to put immediately after the end of the for! Why, you ask? When the elements of the enumerated sequence are exhausted, control passes to the code located in the else block. “And when these elements will not be exhausted?” - when you exit the cycle ahead of schedule according to the break condition.
Using else in this case may seem unreasonable, since else does not quite correctly describe the nature of what is happening, however, this syntactic sugar can be useful when you have a break statement in the loop, and you need to know whether control has passed to it. Suppose we have a computer and a list of people, and we want each of them to use a computer (until one of them breaks it). At the end of the cycle, we want to know if our computer was broken. Usually, we write it this way:
broken = False for person in people: person.use(computer) if computer.is_broken: broken = True break if not broken: print 'The computer is fine!'
Using for..else, we can bring this code to a more readable form:
for person in people: person.use(computer) if computer.is_broken: break else: print 'The computer is fine!'
while ... else
The semantics here are exactly the same as in the previous case. The body of the while loop is executed as long as a certain condition is true - you already know this. If at some point the condition is no longer true, the execution goes to the else branch. The break statement, if the condition reaches it, will interrupt the execution of the entire while..else loop, thus the else branch will not be executed. In a nutshell: the logic of the behavior of while..else is exactly the same as that of for..else.
while usage < 10 and person.want_to_play: person.use(computer) if computer.broken: break else: print 'The computer is fine!'
try ... except ... else
There is some code enclosed in a try block. You want to catch certain exceptions and handle them, but what if no exceptions were thrown during the execution? The else condition comes to the rescue. It will be executed only when no exception has been thrown, and before the finally block (if it exists, of course). It should be noted that the exceptions generated in the else block by the preceding except statements will not be processed:
def get_person(people): try: person = people[3] except IndexError: person = None else: person.do_work() return person
The control will reach the else branch if the IndexError switch has not been thrown. Why is this useful? We can add person.do_work () to a try block, but what happens if do_work () throws an IndexError exception in the process? In this case, it will be caught by our except block, the results of which can be catastrophic (unless of course we have prepared for this in advance - in this case, the IndexError generated by do_work () will be forwarded further, as happens in our get_person function (person )).
Conclusion
Honestly, I did not find much use of the use of the else operator outside of the bunch with if. I believe that in most cases it should not be used with loop operators, since the resulting constructs are not intuitive (although they can be given the “green light” in situations where this results in a more concise and readable code). On the other hand, using else with try is much more intuitive, and may be the best alternative to catching exceptions that need to be forwarded further, or using a flag variable to see if an exception was thrown during the operation of a try block. except.