Using "else" with a loop in Python PREMIUM

Trey Hunner smiling in a t-shirt against a yellow wall
Trey Hunner
3 min. read Python 3.10—3.14
Tags

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!

A for loop with else

Here'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.

What does 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.

Using else as an alternative to setting flags

The 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.

Python's loops support an else block

If 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.

This is a free preview of a premium article. You have 1 preview remaining.