Loops & Iteration

0/5 in this phase0/54 across the roadmap

📖 Concept

Python's loop constructs are designed for clarity and expressiveness. The for loop iterates over any iterable (lists, strings, dicts, files, generators), while while loops run until a condition is false. Python has unique features like else clauses on loops and powerful iteration tools.

for loop: Iterates over any iterable — NOT a traditional C-style counter loop:

for item in iterable:
    process(item)

while loop: Repeats while a condition is true:

while condition:
    do_something()

Loop control:

  • break — exit the loop immediately
  • continue — skip to the next iteration
  • else on loops — executes when the loop completes without break

Essential iteration tools:

  • range(start, stop, step) — generates a sequence of numbers
  • enumerate(iterable, start=0) — yields (index, item) pairs
  • zip(iter1, iter2, ...) — pairs up elements from multiple iterables
  • reversed(sequence) — iterates in reverse
  • sorted(iterable, key=...) — returns sorted list

The else clause on loops is a Python-unique feature that many developers find confusing. It runs when the loop exits normally (not via break). Think of it as "no-break" — if the loop completes without breaking, the else block executes.

💻 Code Example

codeTap to expand ⛶
1# ============================================================
2# for loops — iterating over sequences
3# ============================================================
4fruits = ["apple", "banana", "cherry"]
5
6# Basic iteration
7for fruit in fruits:
8 print(fruit)
9
10# With index — use enumerate (NOT range(len(...)))
11# BAD:
12for i in range(len(fruits)):
13 print(f"{i}: {fruits[i]}")
14
15# GOOD:
16for i, fruit in enumerate(fruits):
17 print(f"{i}: {fruit}")
18
19# Start counting from 1
20for i, fruit in enumerate(fruits, start=1):
21 print(f"#{i}: {fruit}")
22
23# ============================================================
24# range() — generating number sequences
25# ============================================================
26# range(stop)0 to stop-1
27for i in range(5):
28 print(i) # 0, 1, 2, 3, 4
29
30# range(start, stop) — start to stop-1
31for i in range(2, 7):
32 print(i) # 2, 3, 4, 5, 6
33
34# range(start, stop, step)
35for i in range(0, 20, 3):
36 print(i) # 0, 3, 6, 9, 12, 15, 18
37
38# Counting down
39for i in range(10, 0, -1):
40 print(i) # 10, 9, 8, ..., 1
41
42# ============================================================
43# zip() — parallel iteration
44# ============================================================
45names = ["Alice", "Bob", "Charlie"]
46ages = [30, 25, 35]
47cities = ["NYC", "LA", "Chicago"]
48
49# Iterate multiple sequences together
50for name, age, city in zip(names, ages, cities):
51 print(f"{name}, {age}, {city}")
52
53# zip stops at the shortest iterable
54short = [1, 2]
55long = [10, 20, 30, 40]
56print(list(zip(short, long))) # [(1, 10), (2, 20)]
57
58# Use zip_longest to pad with defaults
59from itertools import zip_longest
60print(list(zip_longest(short, long, fillvalue=0)))
61# [(1, 10), (2, 20), (0, 30), (0, 40)]
62
63# Unzipping with zip
64pairs = [("a", 1), ("b", 2), ("c", 3)]
65letters, numbers = zip(*pairs) # Transpose
66print(letters) # ('a', 'b', 'c')
67print(numbers) # (1, 2, 3)
68
69# ============================================================
70# while loops
71# ============================================================
72# Basic countdown
73count = 5
74while count > 0:
75 print(count)
76 count -= 1
77print("Liftoff!")
78
79# Input validation loop
80# while True:
81# value = input("Enter a positive number: ")
82# if value.isdigit() and int(value) > 0:
83# break
84# print("Invalid input, try again")
85
86# ============================================================
87# Loop else clause (runs when loop completes WITHOUT break)
88# ============================================================
89# Use case: searching for an item
90def find_prime_factor(n):
91 for i in range(2, int(n**0.5) + 1):
92 if n % i == 0:
93 print(f"Found factor: {i}")
94 break
95 else:
96 # No factor found — n is prime
97 print(f"{n} is prime!")
98
99find_prime_factor(17) # "17 is prime!"
100find_prime_factor(15) # "Found factor: 3"
101
102# Practical: search with fallback
103def find_user(users, target_id):
104 for user in users:
105 if user["id"] == target_id:
106 print(f"Found: {user['name']}")
107 break
108 else:
109 print(f"User {target_id} not found")
110
111users = [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]
112find_user(users, 2) # "Found: Bob"
113find_user(users, 5) # "User 5 not found"
114
115# ============================================================
116# break and continue
117# ============================================================
118# Skip even numbers, stop at 8
119for i in range(1, 20):
120 if i % 2 == 0:
121 continue # Skip this iteration
122 if i > 8:
123 break # Exit the loop
124 print(i) # 1, 3, 5, 7
125
126# ============================================================
127# Iterating over dictionaries
128# ============================================================
129scores = {"Alice": 95, "Bob": 87, "Charlie": 92}
130
131# Keys (default)
132for name in scores:
133 print(name)
134
135# Values
136for score in scores.values():
137 print(score)
138
139# Both keys and values
140for name, score in scores.items():
141 print(f"{name}: {score}")
142
143# ============================================================
144# Nested loops with product()
145# ============================================================
146from itertools import product
147
148# Instead of nested for loops:
149# for x in range(3):
150# for y in range(3):
151# print(f"({x}, {y})")
152
153# Use itertools.product:
154for x, y in product(range(3), range(3)):
155 print(f"({x}, {y})")

🏋️ Practice Exercise

Exercises:

  1. Write a FizzBuzz implementation using a for loop: print numbers 1-100, but print "Fizz" for multiples of 3, "Buzz" for multiples of 5, and "FizzBuzz" for multiples of both.

  2. Use enumerate and zip to merge two lists into a dictionary with index-based keys: given ["a", "b", "c"] and [1, 2, 3], produce {0: ("a", 1), 1: ("b", 2), 2: ("c", 3)}.

  3. Write a function that uses a for...else loop to check if a number is prime. The else block should handle the "is prime" case.

  4. Implement a simple number guessing game using a while loop: generate a random number 1-100, give hints ("too high"/"too low"), count attempts.

  5. Use itertools.product to generate all possible combinations of sizes (S, M, L, XL) and colors (red, blue, green) as a list of tuples.

  6. Write a nested loop that prints a multiplication table (1-12). Format the output in a clean grid using f-string alignment.

⚠️ Common Mistakes

  • Using range(len(list)) to iterate with index instead of enumerate(). The Pythonic way is for i, item in enumerate(items):.

  • Modifying a list while iterating over it — this causes skipped items or errors. Create a copy: for item in items[:] or use list comprehension to filter.

  • Misunderstanding the else clause on loops — it does NOT run when the loop body encounters a falsy value. It runs when the loop completes without break.

  • Using while True without a clear exit condition (break). Always ensure infinite loops have a reachable break to avoid hanging programs.

  • Not using zip() for parallel iteration. Instead of for i in range(len(a)): print(a[i], b[i]), use for x, y in zip(a, b): print(x, y).

💼 Interview Questions

🎤 Mock Interview

Practice a live interview for Loops & Iteration