for/else and while/else

An else attached to a loop, which runs only when the loop was never broken out of - and is misread by almost everyone the first time.

Overview

The rule, exactly

for item in items:
    if item == target:
        break
else:
    print("not found")

The else runs if the loop ran to completion without hitting break. Iterate zero times? The else runs. Iterate a million times and finish? The else runs. Break out on the first pass? It does not.

The keyword is badly chosen. If it were called nobreak, nobody would ever have been confused by it, and reading it that way in your head is the fastest way to make it click.

loop_else.py

loop_else.py Python 3
Output

                    

loop_else_uses.py

loop_else_uses.py Python 3
Output

                    

Worth knowing

The else runs when the loop ended normally - no break.
It is not "else if the loop did not run". An empty loop still runs the else.
Think of it as nobreak. That is the name it should have had.
It replaces the found = False flag, which is the pattern it exists for.

for/else and while/else: A Practical Guide

A loop can have an else. It runs when the loop finished normally — that is, when no break happened. Almost everyone reads it as "else if the loop did not run", and that is not what it means.

What it replaces

This shape appears constantly:

found = False
for item in items:
    if match(item):
        found = True
        break
if not found:
    ...

The flag exists only to carry one bit of information past the end of the loop. for/else carries it for you: the else block is the "we never found it" branch. One fewer variable, and one fewer chance to forget to set it.

Where it genuinely reads well

Searching, and primality testing, which is the same shape:

for i in range(2, int(n ** 0.5) + 1):
    if n % i == 0:
        return i
else:
    return None

"Tried every divisor, none worked" is exactly the else branch.

while/else too

The same rule applies to while: the else runs when the condition became false, and not when a break ended the loop. That maps onto retry loops neatly — the else is where "we exhausted every attempt" lives.

Should you use it

It is a genuine tool and it is also unfamiliar to many readers. Inside a small function whose whole point is the search, it reads well and saves a flag. Buried in a long function among other loops, a comment or a flag may serve the next person better. Knowing it matters more than using it, because you will meet it in other people's code and it must not be a mystery.

Check yourself

0 of 3

Answer without scrolling back up.

  1. When does a for/else's else block run?

  2. What does for/else replace in ordinary code?

  3. `for x in []: pass` followed by `else: print('hi')` prints what?

Cheat sheet

for/else and while/else

A loop can have an else. It runs when the loop finished normally — that is, when no break happened. Almost everyone reads it as "else if the loop did not run", and that is not what it means.

PYTHON · vizlearn.in/python/loop_else.html

About the author

Ashish Jangra builds and maintains VizLearn. Every module here is written and the visualisation behind it hand-built, so the numbers in a readout come from the same code that draws the picture. Corrections are genuinely welcome and get priority over everything else — if a page states something wrong, or an animation misrepresents what the algorithm does, get in touch.