Nested Loops
Concepts covered: Nested Loops
A loop placed inside another loop runs its whole course once for every step of the outer one. With 3 outer steps and 2 inner steps, the inner body runs 6 times, in a fixed order: both inner steps for outer step 1, then both for outer step 2, then both for outer step 3.
for i in range(1, 4):
print("Outer:", i)
for j in range(1, 3):
print(" Inner:", j)
print()Outer: 1 Inner: 1 Inner: 2 Outer: 2 Inner: 1 Inner: 2 Outer: 3 Inner: 1 Inner: 2
Walking a grid
Tabular data often arrives as a list of rows in which every row is itself a list of cells. That shape is a grid. sales[1] is the second row, a list, and sales[1][2] indexes into that list for its third cell. The outer loop takes the rows and the inner loop takes the cells of the row in hand.
sales = [
[12, 0, 7],
[3, 9, 4],
[0, 0, 15],
]
for store, row in enumerate(sales, start=1):
total = 0
for amount in row:
total += amount
print("store", store, "total", total)Output:
store 1 total 19 store 2 total 16 store 3 total 15
Where total = 0 sits decides what it counts. Inside the outer loop it resets for each store. Moved above the outer loop, it never resets, and the 3 lines read 19, 35 and 50: running totals across all stores.
Wrapping both levels in enumerate gives every cell a pair of coordinates, which is how a data check reports where a bad value sits.
sales = [
[12, 0, 7],
[3, 9, 4],
[0, 0, 15],
]
for r, row in enumerate(sales):
for c, amount in enumerate(row):
if amount == 0:
print("empty cell at row", r, "col", c)Output:
empty cell at row 0 col 1 empty cell at row 2 col 0 empty cell at row 2 col 1
Generating combinations
The second use of nested loops is pairing items. Looping over the same list twice makes every item meet every item: 4 teams give 16 pairs, including each team against itself and every match listed in both orders. To list each match once, start the inner loop 1 position past the outer one with range(i + 1, 4).
teams = ["ants", "bees", "cats", "dogs"]
for i in range(4):
for j in range(i + 1, 4):
print(teams[i], "vs", teams[j])Output:
ants vs bees ants vs cats ants vs dogs bees vs cats bees vs dogs cats vs dogs
| i | teams[i] | j takes | Pairs printed |
|---|---|---|---|
| 0 | ants | 1, 2, 3 | 3 |
| 1 | bees | 2, 3 | 2 |
| 2 | cats | 3 | 1 |
| 3 | dogs | nothing | 0 |
The work a nested loop does is the outer size multiplied by the inner size. A 3 by 3 grid costs 9 inner steps. Comparing 2 lists of records item against item costs far more, and that comparison is where nested loops usually turn slow. A later lesson on joining records removes that inner loop entirely.
- 1,000,000
- 499,500
break exits only the inner loop
break ends the innermost loop it sits in. In a grid search, finding the target breaks the cell loop, and the row loop moves on to the next row unless something tells it to stop as well. The usual signal is a variable set at the moment of the find and checked right after the inner loop.
grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
target = 5
found_row = None
found_col = None
for r, row in enumerate(grid):
for c, value in enumerate(row):
if value == target:
found_row = r
found_col = c
break
if found_row is not None:
break
print("Found", target, "at row", found_row, "col", found_col)Found 5 at row 1 col 1
Every row of this grid holds a 5. What does the program print?
grid = [[1, 5], [5, 2], [3, 5]]
hits = 0
for row in grid:
for value in row:
if value == 5:
hits += 1
break
print(hits)- 1, since the first break ends the whole search
- 6, since break skips only the current comparison
- 3, since each break ends only that row's scan
- 2, since break also skips the row after a match
Stopping the whole scan takes 3 pieces: a variable set when the match is recorded, a break in the inner loop, and an if on that variable placed after the inner loop at the outer loop's indentation, holding a second break.
About this lesson
This section is part of the Loops: Intermediate lesson on DataDriven, the home of data engineering. Lessons cover SQL, Python, Spark, data modeling and pipeline architecture, and each section pairs its explanation with worked examples and practice you run as you go.