Else Is Not for Ifs Only


We all know what else means in control flow. But in Python else can appear on loops and on try/except statements. But what does it do there?

else in loops

The documentation states:

Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the iterable (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement.

In essence this mean that the code of block under else is executed if the for/while is executed successfully. For example:

number = input('Please input upper bound: ')
terminator = input('Please input terminator: ')

for i in range(1, int(number)):
    if i == int(terminator):
        print("I've found the terminator!")
        break
else:
    print("Terminator is not present.")

Now, let’s see what happens if we find a number in defined range, and what happens when a number is not in the range:

$ python else_on_for.py
Please input upper bound: 10
Please input terminator: 5
I've found the terminator!
$ python else_on_for.py
Please input upper bound: 10
Please input terminator: 99
Terminator is not present.

If for iterates through the list, and nothing breaks that iteration along the way, then the block of code under else clause gets executed.

This similarly applies to while statements also. For example, here is a simple program that echoes anything that is written, until a user enters “exit”:

command = input('>>> ')

while command != 'exit':
    # handle a true condition
    print(f'Executing {command}')
    command = input('>>> ')
else:
    # handle a false condition
    print('Bye!')

The output would be the following:

>>> help
Executing help
>>> exit
Bye!

else in try/except

We also find else in try/except statements. However, these statements also use finally keyword. But there is a difference between the two. In full, one can catch an exception like this:

try:
    # do some code
except:
    # handle the potential exception
else:
    # execute only if no exceptions were raised
finally:
    # execute always and cleanup resources

Unlike else, finally is always executed. else is executed only if the code in the try block didn’t raise any exceptions. If you have both else and finally in your try/except block, else must always come before finally.

But what is the purpose of the else in try/except? It gives you the way, to run a piece of code before finalization.

Here’s a simple example of how this works:

for i in range(0, 2):
    try:
        x = 1 / i
    except:
        print('Cannot divide by zero')
    else:
        print(f'1 / {i} = {x}')
    finally:
        print(f'Finished iteration: {i}')

The finalization block will always print and notify us that iteration is completed. However, else will be executed only if numbers are really divisible. Therefore, the output looks like this:

Cannot divide by zero
Finished iteration: 0
1 / 1 = 1.0
Finished iteration: 1

Conclusion

Both for Python programmers and those coming from other languages, oftentimes this syntax is confusing. Although using this feature makes your code more Pythonic, in practice I haven’t seen this construct used too much, so it may make your code less understandable if no one in your team, except you, is using it. However, I wouldn’t discourage you from using it: there are always good use cases where you could utilize this language feature.

python 

We're not spammers, and you can opt-out at any moment. We hate spam as much as you do.

powered by TinyLetter

See also