Why this matters
Loops often need to stop early or skip items. Searching for something should stop as soon as it is found, not keep looking through a million more items. Processing a config file should skip comments and blank lines. Python gives loops three tools for this: break exits a loop immediately, continue jumps to the next iteration, and the loop else clause, a Python specialty, runs code only when a loop finished without breaking, which is exactly the "not found" case of a search.
break: leave the loop now
break ends the innermost loop immediately. Execution continues with the first statement after the loop:
for word in "the quick brown fox".split():
if word == "brown":
print("found brown")
break
print("checked", word)
print("after the loop")
checked the
checked quick
found brown
after the loop
fox was never examined. In a while True: loop, break is the only way out (other than an exception), which is why that pattern always contains one:
while True:
command = input()
if command == "quit":
break
print(f"running {command}")
print("bye")
With input lines ls, pwd, quit:
running ls
running pwd
bye
continue: skip to the next iteration
continue abandons the rest of the current iteration and goes straight to the next one. In a for loop that means taking the next item; in a while loop it means testing the condition again.
for n in range(1, 11):
if n % 2 == 0:
continue
print(n, end=" ")
print()
1 3 5 7 9
continue is most useful at the top of a loop body as a guard: filter out the items you do not care about, then handle the interesting ones without an extra level of indentation:
k = int(input())
for _ in range(k):
line = input().strip()
if not line or line.startswith("#"):
continue # skip blank lines and comments
print("processing:", line)
Without continue, the processing would have to be nested inside an if, and with several filters the nesting gets deep.
Warning: In a
whileloop,continueskips everything below it, including the update of the loop variable if that comes later in the body.i = 0; while i < 5: if i == 2: continue; i += 1loops forever onceiis 2. Put the update before thecontinue, or use aforloop.
The loop else clause
Both for and while may have an else block. It runs when the loop ends normally, that is, when a for runs out of items or a while condition becomes false, and it is skipped if the loop ended with break.
target = 7
for n in [3, 9, 4]:
if n == target:
print("found it")
break
else:
print("not found")
not found
That is a list [3, 9, 4], a collection written in square brackets that you will study in the collections module; looping over it gives each element in turn.
The else is aligned with the for, not with the if. The flow is:
for ... : loop ran out of items --> else block runs
...
break ------------> skip else, continue after the whole statement
else:
...
The name else is admittedly confusing. A good way to remember it: think "no break". The loop else is designed for searches: the loop looks for something and breaks when it finds it; the else handles "searched everything, found nothing".
Without for-else, you need a flag variable:
found = False
for n in [3, 9, 4]:
if n == target:
found = True
break
if not found:
print("not found")
Both are correct. The flag version is more familiar to programmers from other languages; the else version is shorter and keeps the logic in one statement. Use whichever your readers will understand; in this track you should at least be able to read both.
A classic: primality testing
n = int(input())
for d in range(2, n):
if n % d == 0:
print(f"{n} is divisible by {d}")
break
else:
print(f"{n} is prime")
With 21: 21 is divisible by 3. With 23: 23 is prime. For 2 the range is empty, the loop body never runs, no break happens, and the else correctly reports that 2 is prime.
This loop tries every number below n, which is slow for big n. If n = a * b with a <= b, then a * a <= n, so a divisor, if there is one, will be found at or below the square root. Stopping at int(n ** 0.5) + 1 turns a trillion iterations into a million, the kind of improvement that matters far more than any micro-optimization.
break in nested loops
break and continue affect only the innermost loop that contains them:
for row in range(3):
for col in range(3):
if col == 1:
break
print(row, col)
0 0
1 0
2 0
Each break ended only the inner loop; the outer loop carried on with the next row. To leave both loops at once, the cleanest tool is a function with return (functions come next module). Until then, use a flag that the outer loop checks, or the for-else trick:
for a in range(1, 20):
for b in range(a, 20):
if a * a + b * b == 13 * 13:
print(f"found {a}, {b}")
break
else:
continue # inner loop did not break: try the next a
break # inner loop broke: break the outer loop too
found 5, 12
This works but is hard to read; prefer a function once you know them.
Common mistakes
- Misaligned
else. Indented under theif, it becomes theif'selseand runs on every non-matching item: for[3, 9, 4]you would printnot foundthree times. - Expecting
breakto exit all loops. It exits only the innermost one. continuebefore the update in awhileloop. Infinite loop, reported as a time-out.breakoutside a loop.SyntaxError: 'break' outside loop. It cannot be used to leave anifblock.- Using
breakwhere the loop condition would do.while True:with abreakat the very top is justwhile not condition:. Usebreakwhen the exit point is naturally in the middle.
Recap
breakexits the innermost loop immediately;continueskips to its next iteration.continueworks well as a guard at the top of a loop body to filter items.- A loop's
elseruns only if the loop finished withoutbreak: think "no break". It expresses "searched everything, found nothing". - Searching loops should stop as soon as they find the answer; bounding the search (like stopping at the square root) can make programs vastly faster.
Going further: read "break and continue Statements, and else Clauses on Loops" in the official Python tutorial (section 4.4). Then rewrite the nested-loop example above using a flag variable and decide which version you find clearer.