Lesson 5.4: Nested Loops
What You'll Learn
- What nested loops are and how they work
- How to trace through nested loop execution
- How to print patterns with nested loops
- How to build multiplication tables
- How to work with 2D data using nested loops
What Are Nested Loops?
A nested loop is a loop inside another loop. The inner loop runs completely for each iteration of the outer loop.
for i in range(3): # Outer loop: runs 3 times for j in range(2): # Inner loop: runs 2 times PER outer iteration print(f"i={i}, j={j}")
The inner loop ran 2 times for each of the 3 outer iterations, giving us 3 × 2 = 6 total prints. This multiplication is key to understanding nested loops.
Tracing Nested Loops
To understand nested loops, trace through them step by step. Write down the values of each variable at each step.
# Trace this code carefully for row in range(1, 4): for col in range(1, 4): print(f"{row}x{col}={row*col}", end=" ") print() # New line after each row
print() at the end of the outer loop (but outside
the inner loop) creates a new line after each row. This is the standard pattern for printing grids.
Printing Patterns
Nested loops are commonly used to create text-based patterns.
Pattern: Right Triangle
for i in range(1, 6): for j in range(i): print("* ", end="") print()
Pattern: Rectangle
rows = 4 cols = 6 for i in range(rows): for j in range(cols): print("* ", end="") print()
Pattern: Number Triangle
for i in range(1, 6): for j in range(1, i + 1): print(j, end=" ") print()
Multiplication Table
A classic nested loop example: generating a full multiplication table.
# Multiplication table (1-5) print(" ", end="") for i in range(1, 6): print(f"{i:4}", end="") print() print(" " + "----" * 5) for i in range(1, 6): print(f"{i:2} |", end="") for j in range(1, 6): print(f"{i*j:4}", end="") print()
Working with 2D Data
Nested loops are essential when working with data organized in rows and columns, like a grid or a table.
Example: Processing a Grid of Scores
# Student scores: each inner list is one student's scores all_scores = [ [85, 90, 78], # Student 1 [92, 88, 95], # Student 2 [76, 82, 89], # Student 3 ] for i in range(len(all_scores)): total = 0 for score in all_scores[i]: total += score avg = total / len(all_scores[i]) print(f"Student {i+1} average: {avg:.1f}")
Example: Finding a Value in a Grid
grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
target = 5
found = False
for row in range(len(grid)):
for col in range(len(grid[row])):
if grid[row][col] == target:
print(f"Found {target} at row {row}, col {col}")
found = True
if not found:
print(f"{target} not found")
Performance Considerations
Nested loops multiply the number of operations. A loop that runs 100 times inside a loop that runs 100 times means 10,000 total iterations. Be aware of this when working with large data.
# Counting total iterations count = 0 for i in range(10): for j in range(10): count += 1 print(f"Total iterations: {count}") # 100
Try It Yourself!
Create a pattern that looks like this (pyramid with 5 rows):
* *** ***** ******* *********
Hint: For each row, print spaces first, then stars. Row i has (n-i-1) spaces and (2*i+1) stars.
Check Your Understanding
How many times will "X" be printed?
for i in range(4): for j in range(3): print("X")
Answer: 12 times
Outer loop runs 4 times (i = 0, 1, 2, 3). For each outer iteration, the inner loop runs 3 times (j = 0, 1, 2). Total: 4 × 3 = 12.
Key Takeaways
- The inner loop runs completely for each iteration of the outer loop
- Total iterations = outer iterations × inner iterations
- Use
print()(empty) after the inner loop to create a new line for each row - Nested loops are essential for grids, tables, and 2D data
- Trace through small examples step-by-step to build understanding
- Be mindful of performance with deeply nested or large loops