break

break ends the loop it is directly inside — only that one. Code after it in the body, the remaining iterations and the loop’s else block are all skipped.

Control flowPython 3 (all)Live demo
break in a loop
for x in items:
    if found(x):
        break
break skips else
for x in items:
    if found(x):
        break
else:
    not_found()
nested loops
for row in grid:
    for cell in row:
        if cell:
            break  # inner only
Use for
stop a search at the first hit; leave while True
Result
a statement — exits the innermost enclosing loop
Pairs with
for, while, else, continue
Watch out
only exits ONE loop; outside a loop it is a SyntaxError

Demo

Live evaluation
Walk the numbers and stop at the first negative. The trace shows exactly which iterations ran.
Try:
Inputs
numberslistcomma-separated
Code
seen = []
for n in [3, 5, -1, 8]:
    if n < 0:
        break
    seen.append(n)
seen
Result
[3, 5]

In the break tab, everything from the first negative on is missing — the negative itself too, because break comes before append. In the break skips else tab, "else" appears only when no break happened, which includes the empty list. In the nested loops tab, every row i = 0, 1, 2 shows up: break stopped the inner j loop each time, never the outer one.

Syntax slots

NameTypeRequiredDescription
(none)statementnobreak takes no operand and no label. It must be inside the body of a for or while loop (not in a nested def or class).

Common patterns

First match with a not-found branch
for / else replaces a found flag.
def find_admin(users):
    for user in users:
        if user.is_admin:
            break
    else:
        return None
    return user
Loop and a half
while True with the exit test in the middle.
def ask_number(prompt):
    while True:
        text = input(prompt)
        if text.isdigit():
            break
        print("digits only")
    return int(text)
Leave nested loops with return
Put the loops in a function — return exits all of them at once.
def find(grid, target):
    for r, row in enumerate(grid):
        for c, cell in enumerate(row):
            if cell == target:
                return r, c
    return None
First match without a loop
next() with a generator and a default does the search-and-stop in one expression.
def first_negative(nums):
    return next((n for n in nums if n < 0), None)

Examples

1. Stop at the first match
for w in ['a', 'bb', 'ccc']: if len(w) > 1: print('found', w) break
Returns
found bb
2. Code after break never runs
for i in range(3): break print('unreachable') i
Returns
0
3. Leaving while True
n = 0 while True: n += 1 if n == 3: break n
Returns
3
4. break skips the else block
for x in [1, 2, 3]: if x == 2: break else: print('no break') x
Returns
2
5. Only the innermost loop ends
for i in range(2): for j in range(5): break print('outer', i)
Returns
outer 0 outer 1
6. finally still runs on break
for i in range(3): try: break finally: print('cleanup', i)
Returns
cleanup 0
7. break outside a loop
compile('break', '<demo>', 'exec')
Returns
SyntaxError: 'break' outside loop

Pitfalls

1. Expecting break to leave both loops
Python has no labelled break. The inner break ends the inner loop and the outer one carries on. Move the loops into a function and return, or use a flag.
inner break
hits = []
for i in range(3):
    for j in range(3):
        if i + j == 1:
            hits.append((i, j))
            break
hits
[(0, 1), (1, 0)]
return from a function
def first_hit():
    for i in range(3):
        for j in range(3):
            if i + j == 1:
                return (i, j)
first_hit()
(0, 1)
2. break inside a nested function
A def starts a new body; a loop outside it does not count. The code is rejected at compile time.
break in a callback
compile('for x in y:\n    def cb():\n        break', '<demo>', 'exec')
SyntaxError: 'break' outside loop
return a signal
def cb(x):
    return x > 1
for x in [1, 2, 3]:
    if cb(x):
        break
x
2
3. Ending a case with break out of C / JavaScript habit
match / case (and if / elif) never fall through, so they need no break. Inside a loop, that break leaves the whole loop.
break after each case
log = []
for cmd in ['go', 'stop', 'go']:
    match cmd:
        case 'go':
            log.append('moving')
            break
        case 'stop':
            log.append('halt')
log
['moving']
no break needed
log = []
for cmd in ['go', 'stop', 'go']:
    match cmd:
        case 'go':
            log.append('moving')
        case 'stop':
            log.append('halt')
log
['moving', 'halt', 'moving']

When to use

Use it
  • Stopping a search at the first match
  • Leaving a while True loop when its work is done
  • Bailing out of a loop on an error condition you handle right after it
Reach for something else
  • Leaving several nested loops → return from a function
  • Skipping one item and carrying on → continue
  • A search that just returns the match → next(generator, default) or any()

Notes

CPython impl
Compiled to a jump past the loop’s end; any enclosing try / finally or with blocks inside the loop are unwound first
Labels
There is no break label / break 2. PEP 3136 (labelled break and continue) was rejected
finally
break inside try runs the finally block before leaving the loop

FAQ

There is no labelled break. The cleanest way is to move the loops into a function and return. Alternatives: set a flag and check it after the inner loop, use for / else on the inner loop with continue / break, or flatten the loops with itertools.product so a single break is enough.