Phase: 2. Control Flow & Data | Estimated time: 2 hours | Milestone Project: No
- Write nested
forandwhileloops - Print geometric patterns (rectangles, triangles, pyramids, diamonds)
- Generate multiplication tables with nested loops
- Develop intuition for O(n²) time complexity
Nested loops are essential for working with 2D data (grids, tables, matrices). Pattern printing is a classic coding exercise that builds your ability to reason about loops, conditions, and spacing. It's also common in technical interviews — and it's genuinely satisfying to create visual output from logic.
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):
for j in range(4):
print(f"({i},{j})", end=" ")
print()
# Output:
# (0,0) (0,1) (0,2) (0,3)
# (1,0) (1,1) (1,2) (1,3)
# (2,0) (2,1) (2,2) (2,3)The outer loop runs 3 times; each time, the inner loop runs 4 times — that's 3 × 4 = 12 total iterations.
rows = 3
cols = 5
for i in range(rows):
for j in range(cols):
print("*", end="")
print()
# Output:
# *****
# *****
# *****end="" keeps the print on the same line; the empty print() after the inner loop moves to the next line.
Right triangle (increasing stars):
n = 5
for i in range(1, n + 1):
for j in range(i):
print("*", end="")
print()
# Output:
# *
# **
# ***
# ****
# *****The inner loop runs i times on the i-th row — row 1 has 1 star, row 2 has 2 stars, etc.
Inverted right triangle:
n = 5
for i in range(n, 0, -1):
for j in range(i):
print("*", end="")
print()
# Output:
# *****
# ****
# ***
# **
# *n = 5
for i in range(1, n + 1):
# Print spaces
for j in range(n - i):
print(" ", end="")
# Print stars
for j in range(2 * i - 1):
print("*", end="")
print()
# Output:
# *
# ***
# *****
# *******
# *********Spaces decrease as you go down; stars increase as 2*i - 1.
n = 5
# Upper half
for i in range(1, n + 1):
for j in range(n - i):
print(" ", end="")
for j in range(2 * i - 1):
print("*", end="")
print()
# Lower half
for i in range(n - 1, 0, -1):
for j in range(n - i):
print(" ", end="")
for j in range(2 * i - 1):
print("*", end="")
print()for i in range(1, 10):
for j in range(1, 10):
print(f"{i}×{j}={i*j:2}", end=" ")
print()Use format specifiers (:2) to align columns.
If you have two nested loops, each running n times, the inner body runs n × n = n² times:
n = 1000
operations = 0
for i in range(n):
for j in range(n):
operations = operations + 1
print(f"Operations: {operations}") # Operations: 1000000When n doubles, the work quadruples. This is O(n²) — acceptable for small n, but slow for large inputs.
-
Swapping row and column variables — Keep
ifor outer (rows) andjfor inner (columns) by convention. -
Wrong inner loop range — If the inner loop condition doesn't reference the outer variable, you won't get the triangular shape.
-
Forgetting the newline — After the inner loop finishes, you need
print()to move to the next line. -
Hardcoding sizes — Store dimensions in variables (
n = 5) so you can change them easily. -
Not aligning numbers — Without formatting, numbers of different widths produce jagged output.
Let's print a number pyramid:
n = 5
for i in range(1, n + 1):
# Leading spaces
for j in range(n - i):
print(" ", end="")
# Increasing numbers
for j in range(1, i + 1):
print(j, end="")
# Decreasing numbers
for j in range(i - 1, 0, -1):
print(j, end="")
print()
# Output:
# 1
# 121
# 12321
# 1234321
# 123454321Now let's make a checkerboard:
size = 4
for i in range(size):
for j in range(size):
if (i + j) % 2 == 0:
print("■", end=" ")
else:
print("□", end=" ")
print()
# Output:
# ■ □ ■ □
# □ ■ □ ■
# ■ □ ■ □
# □ ■ □ ■- The outer loop runs the inner loop multiple times: total iterations = outer × inner
- Nested loops produce 2D output: the outer loop controls rows, the inner loop controls columns
- Triangular patterns use an inner loop range that depends on the outer variable
- Pyramids and diamonds need separate loops for spaces and stars/numbers
- Multiplication tables are a classic nested-loop application
- O(n²) complexity: doubling the input quadruples the work
- Use
end=""to stay on the same line; callprint()after the inner loop for a newline
Module 018: Lists: Basics — Start working with Python's most versatile data structure: the list.