Warming up the neural circuits...
By the end of this chapter you will:
Computers never get bored. If you need to do the same thing 1,000 times, a loop does it in milliseconds. Without loops, you'd copy-paste code — and copy-paste code is unmaintainable code.
Loops are the foundation of data processing. Every later chapter (lists, files, APIs, databases) builds on the patterns you'll learn here. Master loops, and you can process any collection of data.
Python gives you two loop types and three classic patterns. Click each to see how to use it:
# Loop over a list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# Loop over a string
for char in "hello":
print(char)
# Loop over a range
for i in range(5):
print(i) # 0, 1, 2, 3, 4
# Loop with index
for i, fruit in enumerate(fruits):
print(f"{i}: {fruit}")| Use case | Code |
|---|---|
| Loop over list | for item in items: |
| Loop over string | for char in text: |
| Loop N times | for i in range(N): |
| Loop with | for i, item in enumerate(items): |
| Loop with step | for i in range(0, 10, 2): |
Key insight: Python's for loop is a "for-each" loop — no index management needed.
# Basic while loop
count = 0
while count < 5:
print(count)
count += 1
# User input loop
while True:
command = input("Enter command (or 'quit'): ")
if command == "quit
Pattern 1: Accumulate — build up a result:
total = 0
for num in [1, 2, 3, 4, 5]:
total += num
print(total) # 15Pattern 2: Search — find an item:
numbers = [1, 3, 5, 8
# break — exit early
for i in range(10):
if i == 5:
break
print(i) # 0, 1, 2, 3, 4
# continue — skip iteration
for i in range(5):
if i ==
I need to…
├── Process every item in a collection → for loop
├── Repeat until a condition changes → while loop
├── Build up a result → for + accumulate pattern
├── Find a specific item → for + search pattern
└── Count matching items → for + count patternIn Python, for loops iterate over collections — lists, strings, ranges, and anything else that's iterable. You don't manage an index variable like in C or Java.
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# apple
# banana
# cherryMental model: "For each item in the collection, do this."
for char in "hello":
print(char)
# h
# e
# l
# l
# orange(n) generates numbers from 0 to n-1:
for i in range(5):
print(i)
# 0
# 1
# 2
# 3
# 4range(start, stop) generates from start to stop-1:
for i in range(2, 6):
print(i)
# 2
# 3
# 4
# 5range(start, stop, step) generates with a custom step:
for i in range(0, 10, 2):
print(i)
# 0
# 2
# 4
# 6
# 8If you need both the item and its index, use enumerate():
fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
# 0: apple
#
When to use enumerate:
When NOT to use enumerate:
enumerate — it's clutterwhile loops run as long as a condition is true. Use them when you don't know how many iterations you need.
count = 0
while count < 5:
print(count)
count += 1
# 0
# 1
# 2
# 3
# 4Key facts:
Infinite loop example:
# WARNING: Don't run this — it never stops
count = 0
while count < 5:
print(count)
# Forgot to increment count — infinite loop!When to use while:
# User input loop
while True:
command = input("Enter command (or 'quit'): ")
if command == "quit":
break
print(f"Executing: {command}")break exits the loop immediately:
for i in range(10):
if i == 5:
break
print(i)
# 0
# 1
# 2
# 3
# 4continue skips the of the current iteration and moves to the next:
for i in range(5):
if i == 2:
continue
print(i)
# 0
# 1
# 3
# 4When to use break:
When to use continue:
# Skip negative numbers
numbers = [1, -2, 3, -4, 5]
for num in numbers:
if num < 0:
continue
print(num)
# 1
# 3
Most loops follow one of three patterns. Recognize them, and you can write any loop.
Build up a result by adding to it in each iteration:
# Sum a list
total = 0
for num in [1, 2, 3, 4, 5]:
total += num
print(total) # 15
# Build a string
result = ""
for word in
Find an item that matches a condition:
# Find the first even number
numbers = [1, 3, 5, 8, 9]
for num in numbers:
if num % 2 == 0:
print(f"Found: {num}")
break
# Found: 8
Count items that match a condition:
# Count even numbers
numbers = [1, 2, 3, 4, 5, 6]
count = 0
for num in numbers:
if num % 2 == 0:
count += 1
print(f"Even count: {count
Loops inside loops. The inner loop runs completely for each iteration of the outer loop:
for i in range(3):
for j in range(2):
print(f"({i}, {j})")
# (0, 0)
# (0, 1)
# (1, 0)
# (1, 1)
When to use nested loops:
When NOT to use nested loops:
Processing files:
# Count lines in a file
with open("data.txt") as f:
line_count = 0
for line in f:
line_count += 1
print(f"Total lines: {line_count}")Building reports:
users = [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25},
{"name": "Charlie", "age":
Retry logic:
import time
max_retries = 3
for attempt in range(max_retries):
try:
result = fetch_data()
break
except ConnectionError:
print(f"Attempt {attempt + 1} failed, retrying...")
time.sleep(1
| Mistake | Why it's wrong | Fix |
|---|---|---|
for i in range(len(items)): then items[i] | Unpythonic. Use for item in items: or enumerate(). | for item in items: or for i, item in enumerate(items): |
| Modifying a list while iterating over it | The iterator gets confused — items are skipped or duplicated. | Iterate over a copy: for item in items[:]: or build a new list. |
Infinite while loop | The condition never becomes false. | Make sure you update the condition variable inside the loop. |
Off-by-one with range() | range(n) goes from 0 to n-1, not 0 to n. | Use if you want to . |
List comprehensions: For simple accumulate patterns, list comprehensions are more concise and faster:
# Loop
squares = []
for num in range(5):
squares.append(num ** 2)
# Comprehension (preferred)
squares = [num ** 2 for num in range(5)]We'll cover comprehensions in L1.
Performance: For loops are fast enough for most tasks. For large datasets (millions of items), consider using map(), filter(), or numpy for vectorized operations.
Generator expressions: If you're accumulating into a large list but only need to iterate once, use a generator expression to save memory:
# List (loads everything into memory)
squares = [num ** 2 for num in range(1_000_000)]
# Generator (computes on demand)
squares = (num ** 2 for num in range(1_000_000))We'll cover generators in L2.
[10, 20, 30, 40, 50] using a loop.["apple", "banana", "cherry", "date"].[-3, 5, -1, 8, -2, 7].Beginner:
"What's the difference between for and while loops?"
forloops iterate over a collection (list, string, range) — you know how many iterations you'll do.whileloops run as long as a condition is true — you don't know the iteration count in advance.
"What does enumerate() do?"
enumerate()returns both the index and the value when iterating over a collection.for i, item in enumerate(items):gives youi(the index) anditem(the value).
Senior:
"What happens if you modify a list while iterating over it?"
The iterator gets confused — items may be skipped or processed multiple times. To safely modify a list, iterate over a copy () or build a new list.
for loops iterate over collections: for item in items:.range(n) generates numbers from 0 to n-1. Use range(start, stop, step) for custom ranges.enumerate() gives you both the index and the value.while loops run as long as a condition is true.break exits the loop, continue skips to the next iteration.I want to…
├── Loop over a list → for item in items:
├── Loop with index → for i, item in enumerate(items):
├── Loop N times → for i in range(N):
├── Loop until condition → while condition:
├── Exit early → break
├── Skip iteration → continue
├── Accumulate → total = 0; for x in items: total += x
├── Search → for item in items: if matches(item): break
└── Count → count = 0; for item in items: if matches(item): count += 1What's the difference between 'for' and 'while' loops?
| Use case | Code |
|---|---|
| Condition-driven | while condition: |
| Infinite loop | while True: (with break) |
| Retry logic | while attempts < max: |
Warning: Forgetting to update the condition variable → infinite loop.
Pattern 3: Count — tally matches:
numbers = [1, 2, 3, 4, 5, 6]
count = 0
for num in numbers:
if num % 2 == 0:
count += 1
print(count) # 3| Pattern | Goal | Code |
|---|---|---|
| Accumulate | Build result | total += item |
| Search | Find item | if match: break |
| Count | Tally matches | if match: count += 1 |
| Keyword | Effect |
|---|---|
break | Exit loop immediately |
continue | Skip to next iteration |
else | Runs if loop completes without break |
Key insight: else after a loop runs only if the loop completed normally (no break).
1n| Forgetting to initialize the accumulator | total += num fails if total isn't defined. | Initialize before the loop: total = 0 |
for item in items[:]:"When would you use a while loop instead of a for loop?"
Use
whilewhen you don't know how many iterations you need — e.g., reading user input until they type "quit", polling a resource until it's ready, or retry logic with a maximum attempt count. Useforwhen you're iterating over a known collection.