For loops
A for loop runs a block once for each item in a list. The name after for
takes each value in turn.
items = ["apple", "bread", "milk"]
for item in items:
print("Buying", item)
Three rounds, one per item.
Which lines repeat?
The for line ends with a colon and owns a block, exactly like def and
if. Every line indented under it runs once per item. The first line that
is not indented is outside the loop and runs once, after the loop has
finished.
items = ["apple", "bread", "milk"]
for item in items:
print("Buying", item)
print("...added to basket")
print("Checkout")
Two lines inside the loop, so six lines of output, then Checkout once.
Move print("Checkout") four spaces to the right and run again: it becomes
part of the block and prints three times.
Blocks can sit inside blocks. An if inside a loop is indented four spaces
further than the for, and its own lines four spaces further still:
prices = [40, 25, 60]
for price in prices:
if price > 30:
print(price, "is expensive")
print("checked", price)
print("done")
Read the indentation as nesting: print(price, "is expensive") belongs to
the if, which belongs to the for. print("checked", price) belongs to
the for only, so it runs for every price. print("done") belongs to
nothing and runs once.
Accumulating a result
The most common loop shape: start with a starting value, such as 0 for a total, add to it each time round, and use it at the end.
prices = [40, 25, 2.5]
total = 0
for price in prices:
total += price
print("Total:", total)
total must be created before the loop. Inside, total += price updates it.
The same shape counts things, builds strings, or finds the biggest value.
This one starts from the first price, so it assumes the list is not empty:
prices = [40, 25, 60, 2.5]
biggest = prices[0]
for price in prices:
if price > biggest:
biggest = price
print(biggest)
Looping over numbers
range produces a run of numbers to loop over. With one argument it starts
at 0 and stops before that number, so range(3) gives 0, 1, 2.
for i in range(3):
print(i)
With two arguments, the first is where to start. range(1, 4) gives 1, 2, 3:
it starts at 1 and still stops before 4. The same half-open rule as slicing.
for i in range(1, 4):
print("Box", i)
for year in range(2020, 2024):
print(year)
A third argument is the step. range(0, 20, 5) gives 0, 5, 10, 15. A negative
step counts down, and then the start must be the larger number.
for i in range(0, 20, 5):
print(i)
for i in range(3, 0, -1):
print(i)
print("Go!")
Looping over the characters of a string
A string is a run of characters, so for can walk through those too.
for ch in "bread":
print(ch)
And split, from the string methods page, turns a sentence into a list of
words you can loop over:
line = "apple bread milk"
for word in line.split():
print(word.upper())
Try it
Total price
Write total(prices) that returns the sum of all the numbers in prices.
Use a loop. An empty list totals 0.
total([40, 25, 2.5]) -> 67.5
total([]) -> 0
def total(prices):
result = 0
for price in prices:
...
return result
Count expensive items
Write count_over(prices, limit) that returns how many values in prices
are strictly greater than limit.
count_over([40, 25, 60, 2.5], 30) -> 2
count_over([40, 25, 60, 2.5], 60) -> 0
def count_over(prices, limit):
count = 0
for price in prices:
...
return count
Longest name
Write longest(names) that returns the longest string in the list names.
If two are equally long, return the first of them. The list has at least one
name.
longest(["apple", "bread", "sourdough"]) -> "sourdough"
longest(["milk", "eggs"]) -> "milk"
def longest(names):
best = names[0]
for name in names:
...
return best
Next: More list operations.