Sampling is a compromise: you looked at five records out of five hundred and hope the rest are the same. A loop removes the compromise: checking all five hundred costs the same as checking one.
A loop over a list
live example
statuses = ["NEW", "PAID", "SHIPPED"]
for status in statuses:
print(status)
Run
Running examples is part of paid access. There the same code runs inside the article: editor, run and check next to the paragraph. Free week →
It reads literally: "for each status in statuses — print the status". You do not declare the variable beforehand; the loop does it, putting the next element in on every pass.
The loop body is indented, like an if. Everything indented repeats; everything
not indented runs once, after the loop.
Accumulating a sum and a counter
live example
items = [
{"product": "Grinder", "qty": 1, "price": 4990},
{"product": "Lunchbox", "qty": 2, "price": 890},
]
total = 0
for item in items:
total = total + item["qty"] * item["price"]
print(total) # 6770
Run
Running examples is part of paid access. There the same code runs inside the article: editor, run and check next to the paragraph. Free week →
The accumulator is declared before the loop and set to zero — otherwise it
would reset on every pass. total = total + x is usually shortened to
total += x.
A counter is the same thing with one added:
cancelled = 0
for order in orders:
if order["status"] == "CANCELLED":
cancelled += 1
Note the double indent: the if sits inside the for, and its body is further
right still. Indents show nesting.
A loop over a dict
live example
order = {"id": "ord-042", "status": "PAID", "total": 4990}
for key in order:
print(key) # id, status, total
for key, value in order.items():
print(f"{key} = {value}")
Run
Running examples is part of paid access. There the same code runs inside the article: editor, run and check next to the paragraph. Free week →
items() hands out pairs, unpacked into two variables at once. Handy when you
need to check the whole response — for example, that no field is empty.
Stopping early
for order in orders:
if order["id"] == wanted:
found = order
break # no point searching further
break leaves the loop, continue skips the current pass:
for order in orders:
if order["status"] == "DRAFT":
continue # drafts do not count
...
Building a new list
ids = []
for order in orders:
ids.append(order["id"])
Python has a short form of the same thing — worth recognising in other people's code:
ids = [order["id"] for order in orders]
cancelled = [o for o in orders if o["status"] == "CANCELLED"]
This is a list comprehension. Write whichever is clearer: the long form is more readable, the short one more compact.
Common mistakes
The accumulator inside the loop. total = 0 ends up indented — the sum
resets every pass and the last value survives.
Modifying a list while iterating it. Removing elements from the list you are walking skips items. Build a new list and replace the old one.
Wrong indent. A line that should be inside the loop ends up outside and runs once instead of a hundred times. No error, wrong result; print intermediate values to see it.
What to solve
In short
for item in itemswalks every element; no need to declare the variable.- The accumulator (
total = 0) is declared before the loop, or it resets. - Walk a dict through
.items()— key and value at once. breakleaves the loop,continueskips a pass.- A comprehension
[o["id"] for o in orders]is the same work in short form.
What to read next
- Functions — so the same loop is not copied all over the test.
- assert and errors — how a check reports a break.