Nested Loops & Patterns

Difficulty: Beginner

Nested loops place one loop inside another. The inner loop completes all its iterations for each single iteration of the outer loop. This creates a multiplicative effect -- if the outer loop runs N times and the inner loop runs M times, the total iterations are N * M.

Pattern printing is a classic exercise for understanding nested loops. The outer loop controls the rows and the inner loop controls what is printed in each column of that row. By varying the inner loop's range based on the outer loop variable, you can create triangles, pyramids, diamonds, and other shapes.

Multiplication tables are another natural fit for nested loops. The outer loop iterates over one factor, and the inner loop iterates over the other, printing the product at each position.

When working with nested loops, break and continue only affect the innermost loop they are placed in. To break out of multiple levels, you can use a flag variable or restructure the code into a function that returns early.

Code examples

Right-angled triangle pattern

rows = 5
for i in range(1, rows + 1):
    print("* " * i)

The outer loop controls the row number (1 to 5). String multiplication '* ' * i repeats the star pattern i times for each row.

Number pyramid

rows = 4
for i in range(1, rows + 1):
    for j in range(1, i + 1):
        print(j, end=" ")
    print()

The inner loop prints numbers from 1 to i. Each row i contains numbers 1 through i, creating a growing number triangle.

Multiplication table

size = 4
for i in range(1, size + 1):
    for j in range(1, size + 1):
        print(f"{i*j:4}", end="")
    print()

The outer loop picks the row (multiplier), the inner loop picks the column (multiplicand). The format specifier :4 right-aligns each number in a 4-character width.

Finding pairs with a condition

numbers = [2, 5, 8, 11]
target = 13
print(f"Pairs summing to {target}:")

for i in range(len(numbers)):
    for j in range(i + 1, len(numbers)):
        if numbers[i] + numbers[j] == target:
            print(f"  ({numbers[i]}, {numbers[j]})")

The inner loop starts at i+1 to avoid duplicate pairs. This is a classic two-sum brute-force approach using nested loops.

Key points

Concepts covered

nested loops, star patterns, multiplication table, loop control flow, pattern printing