At close, the day's sales sit on a paper strip, one line per cup. A loop can read every line, but the total needs a starting point before the first cup is counted. What should the accumulator hold at the beginning?
A loop lets one block of code handle many values. The for loop takes each item from an iterable, assigns it to a variable, and runs the body once. This is the backbone of reports, cleaning, and data processing. You will also separate accumulators from built-in aggregations.
Iterate over a collection
The loop variable receives each item in turn. Name it after the item, not after the index. The body is indented and runs once per item.
orders = ["latte", "mocha", "tea"]
for order in orders:
print(order)One line for every order
range produces numbers
range(stop) starts at 0 and stops before stop. range(start, stop) begins at start. range(start, stop, step) skips by step. range is lazy: it produces values as the loop asks for them.
print(list(range(3)))
print(list(range(2, 5)))
print(list(range(0, 10, 2)))Three range shapes
Accumulate a result
Create the accumulator before the loop, update it inside, and print it after the loop. An accumulator can be a number, a list, or a string.
prices = [4.5, 6.0, 3.25]
total = 0
for price in prices:
total += price
print(f"Total: ${total:.2f}")Summing with a loop
Keep running state
An accumulator is a variable that carries a result across iterations. Initialize it before the loop, update it inside the loop, and use it after the loop. If the update is outside the loop, you only keep the last value.
prices = [4.5, 3.0, 6.25]
total = 0
count = 0
for price in prices:
total += price
count += 1
print(count, round(total, 2), round(total / count, 2))One loop, three summary values
Use a built-in when the loop only aggregates
If the loop only computes a sum, count, maximum, or a yes/no condition, a built-in may express the intent more clearly. any() stops at the first true value; all() stops at the first false value. Use a loop when you need several results or custom control flow.
prices = [4.5, 3.0, 6.25]
print(sum(prices), len(prices), max(prices), min(prices))
print(any(price > 6 for price in prices))
print(all(price > 0 for price in prices))Prefer the clearer aggregation
enumerate keeps the line number
enumerate() gives each item and its position, so a skipped line does not shift the error message. Use the start argument to match human line numbers. Do not remove items from a list while iterating over it; build a new list or iterate over a copy. In the receipt project, the line number is what makes an error useful.
lines = ["Latte|2", "", "Tea|1"]
for line_no, line in enumerate(lines, 1):
if not line:
continue
name, qty = line.split("|")
print(line_no, name, int(qty))Positions survive skipped rows
Key points
- for item in items visits each value once.
- range(stop) excludes stop; range(start, stop) includes start.
- Initialize an accumulator before the loop.
- Indentation decides what is inside the loop.
- Accumulators turn a loop into a summary; built-ins are clearer for simple sums.
- enumerate(..., start=1) keeps error messages aligned with human line numbers.
Common mistakes
- Creating the accumulator inside the loop, which resets it every time.
- Expecting range(5) to include 5.
- Changing a list while iterating over it and losing track of items.
- Putting the accumulator update at the wrong indentation level, so only the last value survives.
- Deleting list items while looping over the same list.
Loop over three prices, add them to a total, and print the total with two decimals.
Try it yourself
Change the values, predict the output, then run the code. The Python runtime is downloaded the first time you press Run, so the first run can take a few seconds.
Practice this lesson
12 questions with immediate explanations.