Previous | Tutorial index | Next
Understand how to place loops inside other loops, visualize their execution flow, use them to solve complex problems (like matrix traversal and pattern printing), and recognize performance implications.
A nested loop is simply a loop inside another loop. Think of it as a clock:
The Golden Rule of Nested Loops: For each single iteration of the outer loop, the entire inner loop completes all its iterations from start to finish.
Imagine you have a menu with 3 courses (Appetizer, Main, Dessert). For each course, you have 4 options. To list every possible 3-course meal combination, you'd use 3 nested loops. The outer loop picks the appetizer, the middle loop picks the main for that appetizer, and the inner loop picks the dessert for that main. The total number of combinations is 3 * 4 * 4 = 48.
for i in range(1, 4): # Outer loop (runs 3 times: i = 1, 2, 3)
print(f"Outer: {i}")
for j in range(1, 4): # Inner loop (runs 3 times per outer iteration)
print(f" Inner: {j}")
print("---") # Runs after the inner loop finishes
Step-by-Step Trace:
i = 1 → Print "Outer: 1". Enter inner loop.
j = 1 → Print " Inner: 1"j = 2 → Print " Inner: 2"j = 3 → Print " Inner: 3"i = 2 → Print "Outer: 2". Enter inner loop (starts over at j=1).
j = 1 → Print " Inner: 1"j = 2 → Print " Inner: 2"j = 3 → Print " Inner: 3"i = 3 → (same pattern).Crucial Observation: The inner loop's counter (j) resets to its starting value (1) every time the outer loop advances. It does not remember its previous value (which was 3). This is a common point of confusion for beginners.
Nested loops are the foundation for printing visual patterns in the console. The outer loop usually controls the rows, and the inner loop controls the columns.
for row in range(3): # 3 rows
for col in range(5): # 5 stars per row
print("*", end="") # Print star, stay on same line
print() # Move to the next line after the row ends
Output:
*****
*****
*****
This requires the inner loop's range to depend on the outer loop's current value.
for row in range(1, 6): # row goes 1, 2, 3, 4, 5
for col in range(row): # col runs 0 to row-1
print("*", end="")
print()
Output:
*
**
***
****
*****
This combines spaces and stars.
n = 5
for i in range(1, n+1):
# Print spaces
for j in range(n - i):
print(" ", end="")
# Print stars
for k in range(2*i - 1):
print("*", end="")
print()
Output:
*
***
*****
*******
*********
Nested loops are essential for processing tabular data (lists of lists).
# A 3x3 matrix (grid)
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
# Sum all elements using nested loops
total = 0
for row in matrix: # row is a list (e.g., [1, 2, 3])
for element in row: # element is each number
total += element
print(total) # Output: 45
# Access by index (row, column)
for i in range(len(matrix)): # rows
for j in range(len(matrix[i])): # columns
print(f"matrix[{i}][{j}] = {matrix[i][j]}")
break and continue in Nested LoopsThis is the most important rule to memorize: break and continue only affect the innermost loop they are directly written inside. They do not affect any outer loops.
for i in range(3): # Outer loop
print(f"Row {i}:", end=" ")
for j in range(5): # Inner loop
if j == 3:
break # This breaks ONLY the inner loop!
print(j, end=" ")
print() # This executes after the inner loop breaks.
Output:
Row 0: 0 1 2
Row 1: 0 1 2
Row 2: 0 1 2
How to break out of the OUTER loop from inside? Use a flag variable.
found = False
for i in range(10):
for j in range(10):
if i * j == 42: # Found what we want
print(f"Found at i={i}, j={j}")
found = True
break
if found: # Check the flag to break the outer loop
break
Nested loops multiply the number of iterations.
n items runs n times → O(n) (fast).n items runs n * n = n² times → O(n²).What does this mean?
n = 100, n² = 10,000 iterations – fine.n = 10,000, n² = 100,000,000 iterations – your program will lag severely.n = 100,000, n² is 10,000,000,000 – impossible.Best Practices:
itertools) to flatten it?Nested loops are used to generate all combinations between two sets.
colors = ["red", "blue"]
sizes = ["S", "M", "L"]
for color in colors:
for size in sizes:
print(f"{color} - {size}")
Output:
red - S
red - M
red - L
blue - S
blue - M
blue - L
(This is exactly how clothing inventory works!)
Forgetting to Reset Inner Variables: If you define a variable inside the inner loop and try to use it after the loop, it will hold its last value.
for i in range(3):
for j in range(3):
last_j = j
print(f"After inner: {last_j}") # Prints 2 each time (the last j)
Off-by-One in Pattern Printing:
If you want a triangle with n rows, ensure the inner loop runs exactly row times or row+1 times. Always test with small n (like n=3) to verify.
Using the Same Variable Name in Both Loops:
for i in range(3):
for i in range(3): # Reusing 'i' is confusing and overwrites!
print(i)
# This works in Python but is BAD practice. Use different names (row, col).
break Surprises:
Beginners often think break will stop all loops. It doesn't. Always remember the "innermost only" rule.
Performance Paralysis:
Don't use nested loops to search through a list if you can use in or .index() (which are optimized C-level operations).
Q1: How many times does the line print("Hi") execute?
for x in range(4):
for y in range(3):
print("Hi")
a) 7 times
b) 12 times
c) 4 times
d) 3 times
Q2: What is the output of this code?
for i in range(2, 5):
for j in range(1, i):
print(i, j)
a) (2,1), (3,1), (3,2), (4,1), (4,2), (4,3)
b) (2,2), (3,3), (4,4)
c) (1,2), (2,3), (3,4)
Q3: (True/False) If you use break inside an inner loop, the outer loop also stops immediately.
Q4: What is the total number of iterations for for i in range(100): for j in range(100): pass?
a) 200
b) 10,000
c) 100
Exercise 1: Multiplication Table (Custom Range)
Ask the user for a number n. Print the multiplication table for all numbers from 1 to n (like a 12x12 table, but variable size). Each row should show 1 x i, 2 x i, etc. Format it nicely with \t (tab) to align columns.
n = int(input("Size: "))
for i in range(1, n+1):
for j in range(1, n+1):
print(i*j, end="\t")
print()
Exercise 2: Diagonal Pattern
Print a 5x5 grid where the main diagonal (row == column) contains 1, and all other cells contain 0.
Expected Output:
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
Hint: Use an if statement inside the nested loop.
size = 5
for r in range(size):
for c in range(size):
if r == c:
print("1", end=" ")
else:
print("0", end=" ")
print()
Exercise 3: Sum of Each Row
Given matrix = [[2, 4, 6], [1, 3, 5], [9, 8, 7]], write nested loops to calculate and print the sum of each row individually.
matrix = [[2,4,6], [1,3,5], [9,8,7]]
for row in matrix:
row_sum = sum(row)
print(f"Row sum: {row_sum}")
Exercise 4: Building a Flattened List
Given nested = [[1, 2], [3, 4, 5], [6]], write nested loops to create a single flat list [1, 2, 3, 4, 5, 6].
nested = [[1,2], [3,4,5], [6]]
flat = []
for sub in nested:
for item in sub:
flat.append(item)
print(flat)
Exercise 5: Break the Inner Loop
Write a nested loop that searches for the first number divisible by 7 in a 2D list grid = [[12, 15, 21], [14, 8, 9], [5, 7, 11]]. Print "Found at (row, col)" and use break to stop the inner loop, and a flag to stop the outer loop.
grid = [[12,15,21], [14,8,9], [5,7,11]]
found = False
for r, row in enumerate(grid):
for c, val in enumerate(row):
if val % 7 == 0:
print(f"Found at ({r},{c})")
found = True
break
if found:
break
Question 1: The Right-Aligned Triangle
Write a program that asks the user for a number n. Print a right-aligned triangle of stars with n rows.
Example (n=5):
*
**
***
****
*****
n = int(input("n: "))
for i in range(1, n+1):
print(" " * (n-i) + "*" * i)
Question 2: Transpose a Matrix
Write a program that takes a 2D list matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] and produces its transpose (rows become columns, columns become rows). Print the transposed matrix.
Expected Output:
[1, 4, 7]
[2, 5, 8]
[3, 6, 9]
(Hint: The number of rows in the transpose equals the number of columns in the original).
matrix = [[1,2,3], [4,5,6], [7,8,9]]
trans = [[matrix[r][c] for r in range(len(matrix))] for c in range(len(matrix[0]))]
for row in trans:
print(row)
Question 3: The Prime Number Sieve (Combination Logic)
Write a program that finds all pairs (x, y) where x and y are numbers from 1 to 10, such that x + y is a prime number. Use nested loops and a helper function (or logic) to check primality. Print each pair.
Example Output: (1,1)=2, (1,2)=3, (2,1)=3...
def is_prime(n):
if n < 2:
return False
for d in range(2, int(n**0.5)+1):
if n % d == 0:
return False
return True
for x in range(1, 11):
for y in range(1, 11):
if is_prime(x+y):
print(f"({x},{y})")
Question 4: Multiplication Table with Conditional Coloring
Create a 10x10 multiplication table (1 to 10). Instead of just numbers, if the product is even, print E; if odd, print O. Format it as a grid.
Partial Output (first 3 rows):
E O E O E ...
O E O E O ...
E O E O E ...
for i in range(1, 11):
for j in range(1, 11):
prod = i*j
print("E" if prod%2==0 else "O", end=" ")
print()
Question 5: The Diamond Pattern (Advanced Challenge)
Write a program that prints a diamond shape for a given odd number n (e.g., n=5).
Output for n=5:
*
***
*****
***
*
(Hint: You need an increasing triangle, then a decreasing triangle. Use two separate sets of nested loops, or a single loop with a carefully crafted inner range).
n = int(input("Odd n: "))
for i in range(1, n+1, 2):
print(" " * ((n-i)//2) + "*" * i)
for i in range(n-2, 0, -2):
print(" " * ((n-i)//2) + "*" * i)
Congratulations! You have now mastered nested loops. You understand the cartesian product concept, matrix traversal, pattern generation, and the critical rules of break/continue within nested contexts. This is a huge step toward writing complex, data-driven programs!