You probably think of else as something you can put after an if statement.
And it is!
But in Python, you can also put an else block after a loop!
for loop with elseHere's a for loop with an else statement attached to it:
import os
from pathlib import Path
import sys
readme_filenames = {"readme.md", "readme", "readme.txt", "readme.rst"}
current_directory = Path.cwd()
for path in current_directory.iterdir():
if path.name.lower() in readme_filenames:
readme_path = path
break
else:
sys.exit("No readme file was found.")
print(readme_path)
print("-" * os.get_terminal_size().columns)
print(path.read_text().removesuffix("\n"))
print("-" * os.get_terminal_size().columns)
That looks sort of odd, right?
What do you think that else might be doing?
Pause for a moment to take a guess.
else do in a loop?The first time I saw else on a loop I assumed it might be run whenever the iterable being looped over was empty.
But that's not when else is run.
An else block that's attached to a loop will be run whenever the loop exited without a break statement being hit.
$ python3 readme.py
No readme file was found
Personally, I wish that they used a completely different word for else, like nobreak:
for path in current_directory.iterdir():
if path.name.lower() in readme_filenames:
readme_path = path
break
nobreak: # SyntaxError :(
sys.exit("No readme file was found.")
But that's not what the Python core developers did.
There is no nobreak keyword in Python.
Instead for loops allow an optional else just like if statements do.
else as an alternative to setting flagsThe else clause is often used as an alternative to setting flags to determine whether a loop had a break in it.
For example here's some code (borrowed from this screencast) that will break out of two for loops at the same time using an outer_break variable:
with open("numbers.txt") as number_file:
total = 0
outer_break = False
for line in number_file:
for number in line.split():
n = float(number)
if n < 0:
print("Negative found!", n)
outer_break = True
break
print("Adding", n)
total += n
if outer_break:
break
print("Total:", total)
That outer_break variable allows the outer loop to know whether a break statement was hit so it can break as well.
Instead of using a variable to keep track of breaking, we could have used an else clause with a continue statement followed by a break statement:
with open("numbers.txt") as number_file:
total = 0
for line in number_file:
for number in line.split():
n = float(number)
if n < 0:
print("Negative found!", n)
break
print("Adding", n)
total += n
else:
continue # If no break happened, continue to next line
break # If break happened in inner loop, break from outer loop
print("Total:", total)
This is a bit clever though and I'm not sure it's a big improvement over the approach with a variable.
else blockIf you ever see an else block on a loop, now you know that it's not a typo.
It's just a somewhat obscure Python feature.
The else clause works on both for loops and while loops in Python.
Personally, I try to avoid using else on loops.
In the code that I write, it's rarely useful.
For those rare times when it is particularly useful, I prefer to leave a comment explaining what it does.
Need to fill-in gaps in your Python skills?
Sign up for my Python newsletter where I share one of my favorite Python tips every week.
Sign in to your Python Morsels account to track your progress.
Don't have an account yet? Sign up here.