What you'll learn
- Recognize the five shapes almost every loop takes: accumulate, count, find, filter, and flag
- Build a result across iterations with an accumulator variable
- Stop a search early with
breakand use the loop'selseclause to handle "not found" - Write nested loops for pairs and grids without losing track of which loop you are in
Concept
You know the syntax of loops. What separates someone who can loop from someone who can solve problems is recognizing the handful of shapes that loops take. Nearly every loop you will ever write is one of five patterns, and once you see them, new problems turn into "which pattern is this?"
| Pattern | Starts with | Inside the loop | Ends with |
|---|---|---|---|
| Accumulate | total = 0 |
total += item |
one combined value |
| Count | count = 0 |
if test: count += 1 |
how many matched |
| Find | nothing | if test: result = item; break |
the first match |
| Filter | kept = [] |
if test: kept.append(item) |
a smaller list |
| Flag | found = False |
if test: found = True |
yes or no |
The accumulator is the parent of them all. You create a variable before the loop that holds "the answer so far", update it on every round, and read it after the loop. A sum, a count, a longest word, a running total of a shopping cart: same shape, different update. The variable's starting value is the answer for an empty collection: 0 for a sum, [] for a filtered list, "" for joined text.

Finding is the pattern where break earns its keep: the moment you see what you want, stop. Python adds a twist that most languages lack: a for or while loop can have an else block, which runs only if the loop finished without hitting break. It reads as "search; else, not found", and it removes the need for a separate flag variable in the most common case.

Nested loops are the shape for pairs and grids: every row with every column, every player against every other player. Name the loop variables after what they hold, row and col rather than i and j, and keep the inner body short. If the body grows past a few lines, move it into a function, which you will learn in four lessons.
Code
Accumulate and count over the same list. Both follow the start, update, read shape; only the update differs.
# accumulate.py
prices = [3.5, 12.0, 7.25, 0.99, 15.0]
total = 0
expensive = 0
for price in prices:
total += price
if price > 5:
expensive += 1
print(f"total {total:.2f}, {expensive} items over 5.00")
total 38.74, 3 items over 5.00Find with break, and the loop's else for the not-found case. The second search runs out of names without breaking, so its else fires.
# find.py
names = ["ada", "grace", "linus", "guido"]
for name in names:
if name.startswith("g"):
print("first g-name:", name)
break
else:
print("no g-name found")
for name in names:
if name.startswith("z"):
print("first z-name:", name)
break
else:
print("no z-name found")
first g-name: grace
no z-name foundFilter and flag. The filter keeps a smaller list; the flag remembers whether anything at all matched, and can stop early once it knows.
# filter_flag.py
temps = [18, 22, 31, 27, 35, 19]
hot_days = []
for t in temps:
if t >= 30:
hot_days.append(t)
any_freezing = False
for t in temps:
if t <= 0:
any_freezing = True
break
print("hot days:", hot_days)
print("any freezing:", any_freezing)
hot days: [31, 35]
any freezing: FalseA nested loop over pairs. Each team plays every team after it in the list, so the inner range starts one past the outer index and no pair is repeated.
# pairs.py
teams = ["red", "green", "blue", "gold"]
matches = 0
for i in range(len(teams)):
for j in range(i + 1, len(teams)):
print(f"{teams[i]} vs {teams[j]}")
matches += 1
print("matches:", matches)
red vs green
red vs blue
red vs gold
green vs blue
green vs gold
blue vs gold
matches: 6Try it yourself
Create words.py with a list of ten words. Using one loop per task, find the longest word (accumulate), count the words with more than four letters (count), find the first word containing the letter e with a for/else (find), and build a list of the words that start with a vowel (filter). Print each result on its own line.
Common mistakes
- Starting the accumulator inside the loop.
total = 0inside the block resets it every round, so the answer is only the last item. - Forgetting
breakin a find. Without it the loop keeps going andresultends up as the last match, not the first. - Misreading the loop
else. It is not "if the loop did nothing"; it is "if the loop was not broken out of". An empty list still runs theelse.
What's next
- Almost every loop is accumulate, count, find, filter, or flag: start with the empty answer, update it each round, read it after.
breakstops a search at the first match, and the loop'selseruns only when nobreakhappened.- Nested loops handle pairs and grids; name the variables after what they hold and keep the body short.
You can now write loops that solve problems rather than only repeat. Next you will meet the collection those loops most often run over: the list.