Control Flow
Nested Loops
Loops Inside Loops
You're printing a 10×10 multiplication table. For each row (1-10), you need to print 10 products (row × 1, row × 2, ... row × 10). The outer loop picks the row; the inner loop fills each column.
Multiplication table
Generate a multiplication table using nested loops.
size =
# Print header
print(" ", end="")
for i in range(1, size + 1):
print(f"{i:4d}", end="")
print()
print(" " + "-" * (size * 4))
# Print table
for row in range(1, size + 1):
print(f"{row:2d} |", end="")
for col in range(1, size + 1):
print(f"{row * col:4d}", end="")
print()
size =
# Print header
print(" ", end="")
for i in range(1, size + 1):
print(f"{i:4d}", end="")
print()
print(" " + "-" * (size * 4))
# Print table
for row in range(1, size + 1):
print(f"{row:2d} |", end="")
for col in range(1, size + 1):
print(f"{row * col:4d}", end="")
print()
size =
# Print header
print(" ", end="")
for i in range(1, size + 1):
print(f"{i:4d}", end="")
print()
print(" " + "-" * (size * 4))
# Print table
for row in range(1, size + 1):
print(f"{row:2d} |", end="")
for col in range(1, size + 1):
print(f"{row * col:4d}", end="")
print()
Outer loop: each row (1-10). Inner loop: each column (multiply by 1-10).
Print rectangle of stars
Draw a rectangle pattern with asterisks.
width =
height =
print(f"Rectangle {width}x{height}:")
for row in range(height):
for col in range(width):
print("* ", end="")
print() # New line after each row
# Hollow rectangle
print("\nHollow rectangle:")
for row in range(height):
for col in range(width):
if row == 0 or row == height - 1 or col == 0 or col == width - 1:
print("* ", end="")
else:
print(" ", end="")
print()
# Pythonic: string multiplication
print("\nUsing string multiplication:")
for row in range(height):
print("* " * width)
width =
height =
print(f"Rectangle {width}x{height}:")
for row in range(height):
for col in range(width):
print("* ", end="")
print() # New line after each row
# Hollow rectangle
print("\nHollow rectangle:")
for row in range(height):
for col in range(width):
if row == 0 or row == height - 1 or col == 0 or col == width - 1:
print("* ", end="")
else:
print(" ", end="")
print()
# Pythonic: string multiplication
print("\nUsing string multiplication:")
for row in range(height):
print("* " * width)
width =
height =
print(f"Rectangle {width}x{height}:")
for row in range(height):
for col in range(width):
print("* ", end="")
print() # New line after each row
# Hollow rectangle
print("\nHollow rectangle:")
for row in range(height):
for col in range(width):
if row == 0 or row == height - 1 or col == 0 or col == width - 1:
print("* ", end="")
else:
print(" ", end="")
print()
# Pythonic: string multiplication
print("\nUsing string multiplication:")
for row in range(height):
print("* " * width)
width =
height =
print(f"Rectangle {width}x{height}:")
for row in range(height):
for col in range(width):
print("* ", end="")
print() # New line after each row
# Hollow rectangle
print("\nHollow rectangle:")
for row in range(height):
for col in range(width):
if row == 0 or row == height - 1 or col == 0 or col == width - 1:
print("* ", end="")
else:
print(" ", end="")
print()
# Pythonic: string multiplication
print("\nUsing string multiplication:")
for row in range(height):
print("* " * width)
width =
height =
print(f"Rectangle {width}x{height}:")
for row in range(height):
for col in range(width):
print("* ", end="")
print() # New line after each row
# Hollow rectangle
print("\nHollow rectangle:")
for row in range(height):
for col in range(width):
if row == 0 or row == height - 1 or col == 0 or col == width - 1:
print("* ", end="")
else:
print(" ", end="")
print()
# Pythonic: string multiplication
print("\nUsing string multiplication:")
for row in range(height):
print("* " * width)
width =
height =
print(f"Rectangle {width}x{height}:")
for row in range(height):
for col in range(width):
print("* ", end="")
print() # New line after each row
# Hollow rectangle
print("\nHollow rectangle:")
for row in range(height):
for col in range(width):
if row == 0 or row == height - 1 or col == 0 or col == width - 1:
print("* ", end="")
else:
print(" ", end="")
print()
# Pythonic: string multiplication
print("\nUsing string multiplication:")
for row in range(height):
print("* " * width)
width =
height =
print(f"Rectangle {width}x{height}:")
for row in range(height):
for col in range(width):
print("* ", end="")
print() # New line after each row
# Hollow rectangle
print("\nHollow rectangle:")
for row in range(height):
for col in range(width):
if row == 0 or row == height - 1 or col == 0 or col == width - 1:
print("* ", end="")
else:
print(" ", end="")
print()
# Pythonic: string multiplication
print("\nUsing string multiplication:")
for row in range(height):
print("* " * width)
width =
height =
print(f"Rectangle {width}x{height}:")
for row in range(height):
for col in range(width):
print("* ", end="")
print() # New line after each row
# Hollow rectangle
print("\nHollow rectangle:")
for row in range(height):
for col in range(width):
if row == 0 or row == height - 1 or col == 0 or col == width - 1:
print("* ", end="")
else:
print(" ", end="")
print()
# Pythonic: string multiplication
print("\nUsing string multiplication:")
for row in range(height):
print("* " * width)
width =
height =
print(f"Rectangle {width}x{height}:")
for row in range(height):
for col in range(width):
print("* ", end="")
print() # New line after each row
# Hollow rectangle
print("\nHollow rectangle:")
for row in range(height):
for col in range(width):
if row == 0 or row == height - 1 or col == 0 or col == width - 1:
print("* ", end="")
else:
print(" ", end="")
print()
# Pythonic: string multiplication
print("\nUsing string multiplication:")
for row in range(height):
print("* " * width)
Outer loop: rows. Inner loop: columns within each row.
Print triangle pattern
Create a right triangle by varying inner loop iterations.
height =
# Right triangle (left-aligned)
print("Right triangle:")
for row in range(1, height + 1):
for col in range(row):
print("* ", end="")
print()
# Inverted triangle
print("\nInverted triangle:")
for row in range(height, 0, -1):
for col in range(row):
print("* ", end="")
print()
# Right-aligned triangle
print("\nRight-aligned triangle:")
for row in range(1, height + 1):
print(" " * (height - row), end="") # spaces
print("* " * row) # stars
# Pythonic versions
print("\nPythonic right triangle:")
for row in range(1, height + 1):
print("* " * row)
height =
# Right triangle (left-aligned)
print("Right triangle:")
for row in range(1, height + 1):
for col in range(row):
print("* ", end="")
print()
# Inverted triangle
print("\nInverted triangle:")
for row in range(height, 0, -1):
for col in range(row):
print("* ", end="")
print()
# Right-aligned triangle
print("\nRight-aligned triangle:")
for row in range(1, height + 1):
print(" " * (height - row), end="") # spaces
print("* " * row) # stars
# Pythonic versions
print("\nPythonic right triangle:")
for row in range(1, height + 1):
print("* " * row)
height =
# Right triangle (left-aligned)
print("Right triangle:")
for row in range(1, height + 1):
for col in range(row):
print("* ", end="")
print()
# Inverted triangle
print("\nInverted triangle:")
for row in range(height, 0, -1):
for col in range(row):
print("* ", end="")
print()
# Right-aligned triangle
print("\nRight-aligned triangle:")
for row in range(1, height + 1):
print(" " * (height - row), end="") # spaces
print("* " * row) # stars
# Pythonic versions
print("\nPythonic right triangle:")
for row in range(1, height + 1):
print("* " * row)
The inner loop's limit depends on the outer loop variable.
Search in 2D grid
Find a value in a 2D list (matrix).
grid = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
]
target =
# Print the grid
print("Grid:")
for row in grid:
for cell in row:
print(f"{cell:3d}", end="")
print()
# Search for target (using break with flag)
found_pos = None
for row_idx, row in enumerate(grid):
for col_idx, cell in enumerate(row):
if cell == target:
found_pos = (row_idx, col_idx)
break
if found_pos:
break
if found_pos:
print(f"\nFound {target} at [{found_pos[0]}][{found_pos[1]}]")
else:
print(f"\n{target} not found in grid")
# Pythonic: using next() with generator
print("\nUsing generator expression:")
result = next(
((r, c) for r, row in enumerate(grid) for c, val in enumerate(row) if val == target),
None
)
print(f"Result: {result}")
grid = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
]
target =
# Print the grid
print("Grid:")
for row in grid:
for cell in row:
print(f"{cell:3d}", end="")
print()
# Search for target (using break with flag)
found_pos = None
for row_idx, row in enumerate(grid):
for col_idx, cell in enumerate(row):
if cell == target:
found_pos = (row_idx, col_idx)
break
if found_pos:
break
if found_pos:
print(f"\nFound {target} at [{found_pos[0]}][{found_pos[1]}]")
else:
print(f"\n{target} not found in grid")
# Pythonic: using next() with generator
print("\nUsing generator expression:")
result = next(
((r, c) for r, row in enumerate(grid) for c, val in enumerate(row) if val == target),
None
)
print(f"Result: {result}")
grid = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
]
target =
# Print the grid
print("Grid:")
for row in grid:
for cell in row:
print(f"{cell:3d}", end="")
print()
# Search for target (using break with flag)
found_pos = None
for row_idx, row in enumerate(grid):
for col_idx, cell in enumerate(row):
if cell == target:
found_pos = (row_idx, col_idx)
break
if found_pos:
break
if found_pos:
print(f"\nFound {target} at [{found_pos[0]}][{found_pos[1]}]")
else:
print(f"\n{target} not found in grid")
# Pythonic: using next() with generator
print("\nUsing generator expression:")
result = next(
((r, c) for r, row in enumerate(grid) for c, val in enumerate(row) if val == target),
None
)
print(f"Result: {result}")
grid = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
]
target =
# Print the grid
print("Grid:")
for row in grid:
for cell in row:
print(f"{cell:3d}", end="")
print()
# Search for target (using break with flag)
found_pos = None
for row_idx, row in enumerate(grid):
for col_idx, cell in enumerate(row):
if cell == target:
found_pos = (row_idx, col_idx)
break
if found_pos:
break
if found_pos:
print(f"\nFound {target} at [{found_pos[0]}][{found_pos[1]}]")
else:
print(f"\n{target} not found in grid")
# Pythonic: using next() with generator
print("\nUsing generator expression:")
result = next(
((r, c) for r, row in enumerate(grid) for c, val in enumerate(row) if val == target),
None
)
print(f"Result: {result}")
Nested loops to traverse all [row][col] positions.
Compare all pairs
Find all pairs that satisfy a condition.
numbers =
target_sum =
print(f"Find pairs that sum to {target_sum}:")
# All pairs (avoiding duplicates)
print(f"\nAll pairs with sum {target_sum}:")
for i in range(len(numbers)):
for j in range(i + 1, len(numbers)):
if numbers[i] + numbers[j] == target_sum:
print(f" {numbers[i]} + {numbers[j]} = {target_sum}")
# All possible pairs (cartesian product)
print("\nAll pairs (order matters):")
for i in range(len(numbers)):
for j in range(len(numbers)):
if i != j:
print(f" ({numbers[i]}, {numbers[j]})")
# Pythonic: using itertools
from itertools import combinations, permutations
print(f"\nUsing combinations:")
for a, b in combinations(numbers, 2):
if a + b == target_sum:
print(f" {a} + {b} = {target_sum}")
print("\nUsing permutations:")
for pair in permutations(numbers, 2):
print(f" {pair}")
numbers =
target_sum =
print(f"Find pairs that sum to {target_sum}:")
# All pairs (avoiding duplicates)
print(f"\nAll pairs with sum {target_sum}:")
for i in range(len(numbers)):
for j in range(i + 1, len(numbers)):
if numbers[i] + numbers[j] == target_sum:
print(f" {numbers[i]} + {numbers[j]} = {target_sum}")
# All possible pairs (cartesian product)
print("\nAll pairs (order matters):")
for i in range(len(numbers)):
for j in range(len(numbers)):
if i != j:
print(f" ({numbers[i]}, {numbers[j]})")
# Pythonic: using itertools
from itertools import combinations, permutations
print(f"\nUsing combinations:")
for a, b in combinations(numbers, 2):
if a + b == target_sum:
print(f" {a} + {b} = {target_sum}")
print("\nUsing permutations:")
for pair in permutations(numbers, 2):
print(f" {pair}")
numbers =
target_sum =
print(f"Find pairs that sum to {target_sum}:")
# All pairs (avoiding duplicates)
print(f"\nAll pairs with sum {target_sum}:")
for i in range(len(numbers)):
for j in range(i + 1, len(numbers)):
if numbers[i] + numbers[j] == target_sum:
print(f" {numbers[i]} + {numbers[j]} = {target_sum}")
# All possible pairs (cartesian product)
print("\nAll pairs (order matters):")
for i in range(len(numbers)):
for j in range(len(numbers)):
if i != j:
print(f" ({numbers[i]}, {numbers[j]})")
# Pythonic: using itertools
from itertools import combinations, permutations
print(f"\nUsing combinations:")
for a, b in combinations(numbers, 2):
if a + b == target_sum:
print(f" {a} + {b} = {target_sum}")
print("\nUsing permutations:")
for pair in permutations(numbers, 2):
print(f" {pair}")
numbers =
target_sum =
print(f"Find pairs that sum to {target_sum}:")
# All pairs (avoiding duplicates)
print(f"\nAll pairs with sum {target_sum}:")
for i in range(len(numbers)):
for j in range(i + 1, len(numbers)):
if numbers[i] + numbers[j] == target_sum:
print(f" {numbers[i]} + {numbers[j]} = {target_sum}")
# All possible pairs (cartesian product)
print("\nAll pairs (order matters):")
for i in range(len(numbers)):
for j in range(len(numbers)):
if i != j:
print(f" ({numbers[i]}, {numbers[j]})")
# Pythonic: using itertools
from itertools import combinations, permutations
print(f"\nUsing combinations:")
for a, b in combinations(numbers, 2):
if a + b == target_sum:
print(f" {a} + {b} = {target_sum}")
print("\nUsing permutations:")
for pair in permutations(numbers, 2):
print(f" {pair}")
numbers =
target_sum =
print(f"Find pairs that sum to {target_sum}:")
# All pairs (avoiding duplicates)
print(f"\nAll pairs with sum {target_sum}:")
for i in range(len(numbers)):
for j in range(i + 1, len(numbers)):
if numbers[i] + numbers[j] == target_sum:
print(f" {numbers[i]} + {numbers[j]} = {target_sum}")
# All possible pairs (cartesian product)
print("\nAll pairs (order matters):")
for i in range(len(numbers)):
for j in range(len(numbers)):
if i != j:
print(f" ({numbers[i]}, {numbers[j]})")
# Pythonic: using itertools
from itertools import combinations, permutations
print(f"\nUsing combinations:")
for a, b in combinations(numbers, 2):
if a + b == target_sum:
print(f" {a} + {b} = {target_sum}")
print("\nUsing permutations:")
for pair in permutations(numbers, 2):
print(f" {pair}")
numbers =
target_sum =
print(f"Find pairs that sum to {target_sum}:")
# All pairs (avoiding duplicates)
print(f"\nAll pairs with sum {target_sum}:")
for i in range(len(numbers)):
for j in range(i + 1, len(numbers)):
if numbers[i] + numbers[j] == target_sum:
print(f" {numbers[i]} + {numbers[j]} = {target_sum}")
# All possible pairs (cartesian product)
print("\nAll pairs (order matters):")
for i in range(len(numbers)):
for j in range(len(numbers)):
if i != j:
print(f" ({numbers[i]}, {numbers[j]})")
# Pythonic: using itertools
from itertools import combinations, permutations
print(f"\nUsing combinations:")
for a, b in combinations(numbers, 2):
if a + b == target_sum:
print(f" {a} + {b} = {target_sum}")
print("\nUsing permutations:")
for pair in permutations(numbers, 2):
print(f" {pair}")
Comparing every element with every other element requires O(n²) nested loops.
Exercise: diamond.py
Create a diamond shape pattern with careful loop control