Chapter 4
Repeating Work
Printing ten lines by hand would mean ten print() calls. A loop does it
in a few lines, however many times you need. This chapter covers for, the
loop you'll reach for most, and while, the one you'll reach for when you
don't know the count in advance.
for, over values you already have
for runs a block once for each value in a group, in order:
amounts = [4.50, 12.00, 32.10]
for amount in amounts:
print(amount)
4.5
12.0
32.1amount is a new variable, created by the loop, holding the current value on
each pass. amounts is a list, Chapter 5's whole subject; for now, just
read it as an ordered group of values in square brackets, separated by
commas.
You'll use this shape constantly: loop over a group, do something with each value. Adding them up is the most common version:
amounts = [4.50, 12.00, 32.10]
total = 0
for amount in amounts:
total = total + amount
print(total)
48.6total = total + amount reassigns total to its old value plus the current
one, a running total. This pattern, starting a variable before the loop and
updating it each pass, comes up so often that Python has a shorthand for it:
amounts = [4.50, 12.00, 32.10]
total = 0
for amount in amounts:
total += amount
print(total)
48.6total += amount means exactly total = total + amount. -=, *=, and
/= work the same way for their operators.
range()
range() produces a sequence of numbers to loop over, useful when you want
to repeat something a specific number of times rather than loop over values
you already have:
for i in range(5):
print(i)
0
1
2
3
4range(5) counts from 0 up to, but not including, 5, which is why you get
five numbers, 0 through 4. range() takes up to three arguments: a
start, a stop, and a step.
for i in range(1, 6):
print(i)
1
2
3
4
5for i in range(0, 10, 2):
print(i)
0
2
4
6
8range(1, 6) starts at 1 and stops before 6. range(0, 10, 2) starts at 0,
stops before 10, and counts by 2s. i is a conventional name for a loop
counter; you'll see it constantly in other people's code, and it's fine to
use it when the loop genuinely is just counting, the way it is here.
while
while repeats a block for as long as its condition stays True, checked
before each pass:
total = 0
amounts = [4.50, 12.00, 32.10, 8.75, 45.00]
budget = 20
i = 0
while total < budget and i < len(amounts):
total += amounts[i]
i += 1
print(f"stopped at {total}, after {i} entries")
stopped at 48.6, after 3 entriesThis is the shape you reach for when you don't know in advance how many
times you'll loop, here: "keep adding entries until the running total passes
the budget." amounts[i] picks out one value by position; that's indexing,
which Chapter 5 covers properly.
The single most common while mistake is forgetting to change something the
condition depends on, which loops forever:
total = 0
budget = 20
while total < budget:
print("still under budget")
# total never changes, so this never stops
That prints "still under budget" forever, because total never moves
toward the condition becoming false. If a script you run seems to hang,
check every while loop for exactly this: does something inside the loop
change the value the condition depends on? Ctrl-C in your terminal stops a
runaway script.
break and continue
break exits a loop immediately, for or while, skipping whatever's left:
amounts = [4.50, 12.00, 32.10, 8.75]
for amount in amounts:
if amount > 20:
print(f"found one over 20: {amount}")
break
found one over 20: 32.1Without break, the loop would keep checking every remaining amount even
after finding what it was looking for.
continue skips the rest of the current pass and moves to the next one,
without leaving the loop entirely:
amounts = [4.50, 12.00, 32.10, 8.75]
for amount in amounts:
if amount < 10:
continue
print(amount)
12.0
32.1Amounts under 10 are skipped; everything else prints.
A loop inside a loop
A loop's block can contain anything, including another loop. Here's a list of shopping trips, each one itself a list of amounts:
trips = [[4.50, 12.00], [32.10, 8.75, 45.00]]
grand_total = 0
for trip in trips:
trip_total = 0
for amount in trip:
trip_total += amount
print(f"trip: {trip_total}")
grand_total += trip_total
print(f"grand total: {grand_total}")
trip: 16.5
trip: 85.85
grand total: 102.35The outer for picks one trip at a time; the inner for, fully indented
inside the outer one's block, adds up that single trip's amounts before the
outer loop moves on to the next. trip_total resets to 0 at the start of
every pass through the outer loop, which is exactly why each trip's total
comes out right instead of accumulating across trips. Watch your indentation
carefully here: the inner loop's body is indented twice, once for the outer
for and once more for the inner one.
Practice
Try each of these before you read the solution under it.
- Given
amounts = [4.50, 12.00, 32.10, 8.75, 45.00], print each one that's greater than 10, usingfor. - Print every third number from 0 up to and including 30, using
range()with a step. - Using
while, count how many amounts fromamounts = [4.50, 12.00, 32.10, 8.75, 45.00]it takes, added in order, to reach or pass a total of 50. - Given
trips = [[6.00, 3.50], [10.00, 4.25, 4.25]], print each trip's total on its own line, using a loop inside a loop.
Solutions
1.
amounts = [4.50, 12.00, 32.10, 8.75, 45.00]
for amount in amounts:
if amount > 10:
print(amount)
12.0
32.1
45.02. range(0, 31, 3) needs 31, not 30, as the stop, since range never
includes its stop value.
for n in range(0, 31, 3):
print(n)
0
3
6
9
12
15
18
21
24
27
303. A while loop with a counter and a running total, same shape as the
budget example above.
amounts = [4.50, 12.00, 32.10, 8.75, 45.00]
total = 0
count = 0
while total < 50 and count < len(amounts):
total += amounts[count]
count += 1
print(f"{count} amounts, total {total}")
4 amounts, total 57.354.
trips = [[6.00, 3.50], [10.00, 4.25, 4.25]]
for trip in trips:
trip_total = 0
for amount in trip:
trip_total += amount
print(trip_total)
9.5
18.5Where this leaves you
You can repeat work with for over a group of values or range() of
numbers, use while when you don't know the count ahead of time, and you
know what an infinite loop looks like and how to avoid one. You've also
leaned on lists without formally meeting them yet. Chapter 5 makes the list
itself the subject.