Kodewick
Lesson 13 of 31Contents

for loops

Lesson 13 of 31 · Part 2 · Collections and loops · about 20 minutes

A loop runs the same lines again and again, once for each item. Instead of writing print five times for five lamps, you write it once and let the loop repeat it. This lesson is the best place to use Step: you can watch the loop go around and the loop variable change each time.

main.py
1lamps = ["Mill Road", "Bridge", "Market"]2for lamp in lamps:3    print("Lighting", lamp)4print("All lit")
Output
Lighting Mill Road
Lighting Bridge
Lighting Market
All lit

How a for loop works

PieceWhat it does
for lamp in lamps:Take the items of lamps one by one. Each time around, lamp holds the current item. The line ends with a colon.
the indented linesThe body: they run once for every item.
the first line that is not indentedIt is after the loop, so it runs once, when the loop is done.

You choose the name of the loop variable. Pick one that says what a single item is: for lamp in lamps, for house in houses.

Guess first

How many times is done printed?

1for n in [1, 2, 3]:2    print(n)3print("done")

Looping over a string

A string is a sequence of characters, so a for loop can walk through it one character at a time.

main.py
1for letter in "ore":2    print(letter, letter.upper())
Output
o O
r R
e E

Counting with range()

To repeat something a number of times, loop over range(). It produces numbers on demand. Wrap it in list() to see them all at once:

main.py
1print(list(range(5)))2print(list(range(2, 6)))3print(list(range(0, 20, 5)))4print(list(range(5, 0, -1)))
Output
[0, 1, 2, 3, 4]
[2, 3, 4, 5]
[0, 5, 10, 15]
[5, 4, 3, 2, 1]
FormCountsExample
range(stop)from 0 up to, but not including, stoprange(5) is 0 to 4
range(start, stop)from start up to, not including, stoprange(2, 6) is 2 to 5
range(start, stop, step)in jumps of step; a negative step counts downrange(5, 0, -1) is 5 to 1

The end number is never included. range(5) gives exactly 5 numbers, which is why it is the usual way to say "do this 5 times":

main.py
1for night in range(3):2    print("Night", night + 1, "- lamps on")
Output
Night 1 - lamps on
Night 2 - lamps on
Night 3 - lamps on
Guess first

What does this print?

1for i in range(5, 2):2    print(i)3print("end")

Adding up as you go

A common pattern: make a variable before the loop, update it inside, use it after. An if inside the loop lets you act only on some items.

main.py
1loads = [3, 8, 2, 6]2total = 03big = 04for ore in loads:5    total += ore6    if ore >= 5:7        big += 18print("Total ore:", total)9print("Big loads:", big)
Output
Total ore: 19
Big loads: 2

Tip: Press Step here and watch total and big change each time around. If total = 0 were inside the loop, it would be reset every time.

Numbering with enumerate()

Sometimes you need the position as well as the item. enumerate() gives you both, as a pair you unpack into two names, just like tuple unpacking. It counts from 0 unless you give start.

main.py
1houses = ["bakery", "forge", "mill"]2for i, house in enumerate(houses):3    print(i, house)4for number, house in enumerate(houses, start=1):5    print(f"{number}. {house}")
Output
0 bakery
1 forge
2 mill
1. bakery
2. forge
3. mill

Two lists side by side with zip()

zip() walks through two lists together. Each time around you get one item from each. If the lists differ in length, it stops at the end of the shorter one.

main.py
1miners = ["Ada", "Ben", "Cleo"]2amounts = [12, 7, 9]3for name, amount in zip(miners, amounts):4    print(f"{name} mined {amount} ore")
Output
Ada mined 12 ore
Ben mined 7 ore
Cleo mined 9 ore

Looping over a dictionary

A loop over a dictionary gives you its keys. Loop over .items() to get each key with its value.

main.py
1stock = {"iron": 14, "copper": 6, "gold": 2}2for item in stock:3    print(item)4for item, count in stock.items():5    print(f"{item}: {count}")
Output
iron
copper
gold
iron: 14
copper: 6
gold: 2

Use .values() when you only need the values. The items come out in the order they were added.

break and continue

break leaves the loop at once; nothing more of it runs. Here the loop stops at the first empty cart, and the 5 and the 9 are never unloaded:

main.py
1loads = [4, 7, 0, 5, 9]2for ore in loads:3    if ore == 0:4        print("Empty cart, stop")5        break6    print("Unload", ore)
Output
Unload 4
Unload 7
Empty cart, stop

continue skips the rest of the body for this item and goes on with the next one:

main.py
1lamps = ["on", "off", "on", "off"]2for i, state in enumerate(lamps):3    if state == "on":4        continue5    print("Light lamp", i)
Output
Light lamp 1
Light lamp 3
KeywordWhat happens
breakLeave the loop now. The program goes on after the loop.
continueSkip to the next item. The loop goes on.

Practice

Write the code, then press Check. A hint costs nothing; the answer is there when you need it. Use Step if the output is not what you expect.

Exercise 1

Countdown

Change the range() so the program counts down 3, 2, 1, then prints Go!.

It should print
3
2
1
Go!
exercise1.py
1for n in range(3):2    print(n)3print("Go!")
Output
Press Run or Ctrl+Enter
Exercise 2

One to a hundred

Use a loop to add up all the whole numbers from 1 to 100, then print the total.

It should print
5050
exercise2.py
1total = 02# Your loop here3print(total)
Output
Press Run or Ctrl+Enter
Exercise 3

Running low

Print only the items that have fewer than 5 left, as item: count.

It should print
copper: 3
gold: 0
exercise3.py
1stock = {"iron": 14, "copper": 3, "coal": 22, "gold": 0}2for item in stock:3    print(item)
Output
Press Run or Ctrl+Enter

What you learned

  • for x in something: runs the indented body once for each item of a list, string or dictionary.
  • range(stop), range(start, stop) and range(start, stop, step) count; the stop is never included, and a range can be empty.
  • Set a variable before the loop and update it inside to add up or count; use if to pick items.
  • enumerate() gives the position with each item; zip() walks two lists together; .items() gives keys with values.
  • break leaves the loop; continue skips to the next item.