Loops with an else clause
suggest changeThe for
and while
compound statements (loops) can optionally have an else
clause (in practice, this usage is fairly rare).
The else
clause only executes after a for
loop terminates by iterating to completion, or after a while
loop terminates by its conditional expression becoming false.
for i in range(3):
print(i)
else:
print('done')
i = 0
while i < 3:
print(i)
i += 1
else:
print('done')
output:
0
1
2
done
The else
clause does not execute if the loop terminates some other way (through a break
statement or by raising an exception):
for i in range(2):
print(i)
if i == 1:
break
else:
print('done')
output:
0
1
Most other programming languages lack this optional else
clause of loops. The use of the keyword else
in particular is often considered confusing.
The original concept for such a clause dates back to Donald Knuth and the meaning of the else
keyword becomes clear if we rewrite a loop in terms of if
statements and goto
statements from earlier days before structured programming or from a lower-level assembly language.
For example:
while loop_condition():
...
if break_condition():
break
...
is equivalent to:
# pseudocode
<<start>>:
if loop_condition():
...
if break_condition():
goto <<end>>
...
goto <<start>>
<<end>>:
These remain equivalent if we attach an else
clause to each of them.
For example:
while loop_condition():
...
if break_condition():
break
...
else:
print('done')
is equivalent to:
# pseudocode
<<start>>:
if loop_condition():
...
if break_condition():
goto <<end>>
...
goto <<start>>
else:
print('done')
<<end>>:
A for
loop with an else
clause can be understood the same way. Conceptually, there is a loop condition that remains True as long as the iterable object or sequence still has some remaining elements.
Why would one use this strange construct?
The main use case for the for...else
construct is a concise implementation of search as for instance:
a = [1, 2, 3, 4]
for i in a:
if type(i) is not int:
print(i)
break
else:
print("no exception")
To make the else
in this construct less confusing one can think of it as “if not break” or “if not found”.
Some discussions on this can be found in [Python-ideas] Summary of for…else threads, Why does python use ‘else’ after for and while loops?, and Else Clauses on Loop Statements