Python Break Out of Nested Loops
To break out of nested loops in Python, remember that break only stops the innermost loop. To stop both, use return in a function, a flag, or for ... else.
Read Nested Loops & Ifs and break and continue first.
break stops only the inner loop
grid = [[1, 2, 3], [4, 5, 6]]
for row in grid:
for value in row:
if value == 2:
print("found 2")
break
print("finished a row")
found 2 prints, then finished a row twice. The break left the inner loop, but the outer loop carried on to the second row.
Stop both loops with return
Put the search in a function. return leaves the function, so it ends every loop inside it at once.
def find(grid, target):
for r in range(len(grid)):
for c in range(len(grid[r])):
if grid[r][c] == target:
return r, c
return None
grid = [[1, 2, 3], [4, 5, 6]]
print(find(grid, 5))
print(find(grid, 9))
This prints (1, 1), then None. This is usually the clearest choice: the function name says what the loops are for.
Stop both loops with a flag
Without a function, set a flag in the inner loop and check it after the inner loop ends.
grid = [[1, 2, 3], [4, 5, 6]]
found = False
for row in grid:
for value in row:
if value == 2:
found = True
break
if found:
break
print("found:", found)
This prints found: True. Forget the second if found: break and the outer loop keeps going, which is the classic bug.
Stop both loops with for ... else
The inner loop's else runs only when it finished without break. continue there skips the outer break.
grid = [[1, 2, 3], [4, 5, 6]]
for row in grid:
for value in row:
if value == 5:
break
else:
continue
break
print("stopped at row", row)
This prints stopped at row [4, 5, 6]. It works, but many readers find it hard to follow. Prefer return when you can.
Note: Python has no labelled break like some other languages, so these three patterns are the standard options.
See also: Python for else, Stopping a Search with return.
Your turn
Complete first_negative(grid) so it returns the row and column of the first negative number, or None if there isn't one. Stop searching as soon as you find it.
def first_negative(grid):
# loop over rows and columns; return (row, column) at the first value below 0
return None
print(first_negative([[3, 1], [4, -2], [-5, 0]]))
print(first_negative([[1, 2], [3, 4]]))
Expected output
(1, 1)
None