Chapter 2 · Apprentice

for loops and accumulation

A for loop walks through the items of a collection — a list, a string, a range — one at a time, running the body once per item. Use it when you know what you're iterating over (which is most of the time).

The variable after for takes each value in turn: for n in [2, 3, 5]: gives n the value 2, then 3, then 5.

The accumulation pattern is the workhorse: start a variable outside the loop (a total at 0, an empty list [], a count at 0), then update it each pass. After the loop, that variable holds the combined result.

range(n) produces 0, 1, ..., n-1 — perfect for "do this n times" or counting. range(start, stop, step) gives more control.

Syntax

for item in collection:
    # body runs once per item

for i in range(5):        # 0,1,2,3,4
    ...
for i in range(2, 10, 2): # 2,4,6,8
    ...

# Accumulation:
total = 0
for n in numbers:
    total = total + n

Worked examples

Accumulate a running total

def total(sizes):
    running = 0
    for n in sizes:
        running = running + n
    return running

print(total([2, 3, 5]))   # 10
print(total([]))          # 0

Build a new list as you go

words = ["api", "db", "cache"]
shouted = []
for w in words:
    shouted.append(w.upper())
print(shouted)   # ['API', 'DB', 'CACHE']

range() for counting and repetition

for i in range(3):
    print(f"attempt {i + 1}")
# attempt 1
# attempt 2
# attempt 3

Common mistakes & gotchas

Initialising the accumulator inside the loop

Putting total = 0 *inside* the loop resets it every pass, so you only ever get the last item. The accumulator must be set up *before* the loop.

range(n) stops at n-1

range(5) is 0,1,2,3,4 — five values, not including 5. range(1, 5) is 1,2,3,4. The stop value is always excluded.

Modifying a list while looping over it

Adding to or removing from a list inside a for over that same list causes skipped items or surprising behaviour. Iterate over a copy (for x in items[:]) or build a new list instead.

Why it matters

Most data comes in collections — rows, records, lines, results. The for-loop-with-an-accumulator is how you turn many values into one answer (a sum, a filtered list, a count), and you'll write it thousands of times. Python's built-ins like `sum()` exist, but owning the manual pattern means you can do it when no built-in fits.