Loops
Repeat work over every item without copy-pasting code.
Why it matters
AI work is repetitive in exactly the way computers are good at. Score 500 headlines. Send 20 prompts and compare the answers. Process every row of an export. Run a test over a whole set of examples. When you train a neural network in Phase 4, the training itself is a loop that runs thousands of times. Loops let you say "do this for each one" once, instead of copying code.
What you'll be able to do
- Repeat code for every item in a list with a for loop
- Use the accumulator pattern to total, count and track the best item
- Filter items into a new list with if inside a loop
- Use range, enumerate, zip, while, break and continue
What it covers
- Do something for every item
- The accumulator pattern
- Looping over rows
- while: repeat until something changes
- Worked example: a week of ad results
- Reading a loop by hand
- Name what you're looping over
Do something for every item
Think of stuffing envelopes for a mailing: take the next letter, fold it, put it in, seal it, repeat until the pile is gone. A for loop is that. It runs a block of code once for each item in a list:
channels = ["search", "display", "email"] for channel in channels: print("Checking", channel) print("Done")
Read it as "for each channel in channels, do the indented block". Each pass through the loop is called an iteration. On each one, the variable channel holds the next item. You choose its name: pick the singular of the list's name, so the code reads naturally.
The block follows the same indenting rules as if. The unindented print("Done") runs once, after the loop finishes.
A loop works on a string too, one character at a time.
Watch spend take each value in turn while total grows. The loop body (line 4) runs four times, then Python moves on to the print.
The accumulator pattern
That stepper shows the most common loop shape there is:
- Before the loop, create a variable with a starting value:
0for a total or a count,[]for a list you'll fill. - Inside the loop, update it using the current item.
- After the loop, use the result.
Combined with if, the same shape counts, filters and finds the best item:
ctrs = [0.031, 0.012, 0.044, 0.019, 0.027] count_strong = 0 weak = [] best = 0 for ctr in ctrs: if ctr >= 0.025: count_strong += 1 else: weak.append(ctr) if ctr > best: best = ctr print("Strong:", count_strong) print("Weak:", weak) print("Best:", best)
Python also has sum() and max() built in, and for a plain total you'd use them. The pattern matters for everything they can't do. Counting only some items. Collecting the names that failed a check. Or tracking the best item's name, not just its value.
count = 0 for word in ["sale", "SALE", "Sale", "deal"]: if word.lower() == "sale": count += 1 print(count)
Show the answer
3
Lowercasing makes "sale", "SALE" and "Sale" all equal to "sale", so count goes up three times, and "deal" adds nothing. It ends at 3.
Looping over rows
Sometimes each item is itself a list, such as a row with a name and some numbers. Then you can unpack it straight into separate variables in the for line:
campaigns = [
["Spring Sale", 5000, 3120.5],
["Retargeting", 2000, 2150.0],
["Newsletter", 500, 120.0],
]
for name, budget, spend in campaigns:
remaining = budget - spend
print(f"{name}: {remaining:,.2f} left")
The number of names before in must match the length of each row.
Counting with range, numbering with enumerate, pairing with zip
range() produces a sequence of whole numbers to loop over:
range(5)is 0 up to, but not including, 5.range(1, 6)starts at 1.range(0, 100, 25)counts in steps of 25.
for week in range(1, 4): print("Week", week) print(list(range(0, 100, 25))) # list() shows the numbers range produces
enumerate() gives you a position number alongside each item, and zip() walks through two lists side by side:
headlines = ["Spring sale", "New arrivals", "Last chance"] for number, headline in enumerate(headlines, start=1): print(f"{number}. {headline}") names = ["Search", "Display", "Email"] spends = [3120.5, 1890, 120] for name, spend in zip(names, spends): print(f"{name}: {spend:,.2f}")
while: repeat until something changes
A while loop repeats as long as its condition stays True. It's like stirring until the sauce thickens: you don't know how many stirs it'll take. Use it when you don't know in advance how many repeats you need:
budget = 1000 weeks = 0 while budget < 5000: budget = budget * 1.4 # grow 40% a week weeks += 1 print(weeks, "weeks to pass 5000; budget is now", round(budget))
Something inside the loop must eventually make the condition False. If nothing does, the loop runs forever. That's called an infinite loop. The academy stops your code after a few seconds if you write one by accident.
break and continue
break leaves the loop straight away. continue skips the rest of the current iteration and moves on to the next item.
campaigns = [["Search", 5000, 3120.5], ["Display", 2000, 2150], ["Email", 500, 620]] for name, budget, spend in campaigns: if spend > budget: print("First campaign over budget:", name) break emails = ["ana@shop.com", "", "ben@shop.com", " ", "cy@shop.com"] sent = 0 for email in emails: if email.strip() == "": continue # skip blanks sent += 1 print("Sent to", sent, "addresses")
break stopped at Display, so Email was never checked, even though it's also over budget.
total = 0 for n in range(1, 4): total += n print(total)
Show the answer
6
range(1, 4) gives 1, 2 and 3 (it stops before 4). Adding them up: 1 + 2 + 3 = 6.
Worked example: a week of ad results
Each row is a headline, its impressions and its clicks. In one pass, total the clicks, find the headline with the best click-through rate, and list every headline under 2%.
ads = [
["Headline A", 12000, 360],
["Headline B", 9500, 180],
["Headline C", 15000, 600],
["Headline D", 4000, 40],
]
total_clicks = 0
best_name = ""
best_ctr = 0
weak = []
for name, impressions, clicks in ads:
ctr = clicks / impressions
total_clicks += clicks
if ctr > best_ctr:
best_ctr = ctr
best_name = name
if ctr < 0.02:
weak.append(name)
print(f"Total clicks: {total_clicks:,}")
print(f"Best: {best_name} ({best_ctr:.1%})")
print(f"Under 2% CTR: {weak}")Four accumulators share one loop: a running total, the best value so far, the name that goes with it, and a list of names that fail a check. Notice that best_ctr and best_name are updated together inside the same if, so they always describe the same headline. The two if statements are separate (not if/elif) because a headline could, in principle, be both the best and weak, and each check must run independently.
for i in range(4): run?Show the answer
4
range(4) produces 0, 1, 2 and 3: four numbers, so four iterations.
Reading a loop by hand
When a loop gives the wrong answer, don't stare at it. Play computer with a pencil. Write each variable as a column, and fill in one row for each time through.
For total = 0, then for n in [2, 5, 3]: total += n:
| n | total after this pass |
|---|---|
| 2 | 2 |
| 5 | 7 |
| 3 | 10 |
It takes a minute, and it shows exactly where your idea and the code part ways. The step-through view earlier in this lesson does the same thing automatically.
Four bugs you'll write at least once
Forgetting to add. total = n replaces the total on each pass, so you end up with the last number. You wanted total += n.
Starting in the wrong place. If total = 0 sits inside the loop, the total resets on every pass. Starting values go above the loop.
Printing in the wrong place. A print indented inside the loop runs on every pass. If you want one final answer, move it back to the left, level with for.
A while that never ends. A while loop stops only when its condition turns false, so something inside must change it. If nothing does, the program runs forever. In the browser, the run limit stops it. On your own computer, press Ctrl+C.
Remember, too, that range(5) means 0, 1, 2, 3 and 4. It starts at 0 and stops before 5. If you want 1 to 5, write range(1, 6).
Name what you're looping over
Plural for the list and singular for the item, as in for price in prices, makes loops much easier to read later.
Practice what you just read
- 8 code examples you can edit and run
- a practice exercise that checks your code
- a 6-question quiz
- 6 review cards for spaced repetition
Try a quiz question
What does this print?
total = 0
for n in [4, 6, 10]:
total = n
print(total)