Iterating over a list

Loops over items and indexes, totals, counts, min and max, and linear search.

F3.4Strings, lists and recordsGCSE15 min

Do this lesson in the simulator

A list is only useful if you can work through it. This lesson puts together two things you already know, lists and loops, into the most common thing programs do with data: go through every item and do something with it.

for over the items

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

legs = [20, 15, 30, 15]
for length in legs:
    print("driving", length, "cm")
    forward(60, distance=length)
    turn_right(30, angle=90)
print("finished at", position())

Run this in the simulator

for length in legs visits each item in turn, first to last, putting it in length. No range and no index needed when you only want the items. Change the list and the drive changes: the program is now driven by data.

for over the indexes

When you need the position as well as the item, loop over range(len(...)):

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

colours = ["red", "orange", "green"]
for i in range(len(colours)):
    print("step", i, "is", colours[i])
    led(colours[i])
    wait(0.5)

for i, colour in enumerate(colours):
    print(i, colour)

Run this in the simulator

range(len(colours)) gives 0, 1, 2: every valid index. enumerate gives the index and the item together, which is often tidier.

The patterns, over a list

The loop patterns from lesson F2.7 work on any list. Python also has built-in functions for the common ones:

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

readings = [41.0, 35.5, 30.2, 25.8, 20.1]

total = 0
for r in readings:
    total = total + r
print("total", total, "or with sum:", sum(readings))
print("average", total / len(readings))

close = 0
for r in readings:
    if r < 30:
        close = close + 1
print(close, "readings under 30 cm")

print("smallest", min(readings), "largest", max(readings))

Run this in the simulator

It is worth being able to write the loop yourself as well as use sum, min and max: exam questions often ask for the algorithm, and a loop can do things the built-ins cannot, such as count only the readings under 30.

Readings from the robot

Collect first, then work through the list:

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

readings = []
for step in range(6):
    readings.append(distance())
    forward(50, distance=6)

print("readings:", readings)
biggest_drop = 0
for i in range(1, len(readings)):
    drop = readings[i - 1] - readings[i]
    if drop > biggest_drop:
        biggest_drop = drop
print("biggest change between two readings:", round(biggest_drop, 1), "cm")

Run this in the simulator

The second loop starts at index 1 so that readings[i - 1] always exists. Comparing each item with the one before it is another pattern you will use often.

Searching a list

Linear search looks at each item in turn until it finds the one it wants:

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

names = ["Ada", "Alan", "Grace", "Tim"]
target = input("Who are you looking for? ")
found = False
for i in range(len(names)):
    if names[i] == target:
        print(target, "is at index", i)
        found = True
        break
if not found:
    print(target, "is not in the list")

Run this in the simulator

The found flag remembers whether the loop succeeded, and break stops looking once it has. Module F5 compares this with faster ways to search.

Task: sensor log

Drive forward in five steps of 8 cm, recording distance() before each step in a list. Then print four lines: readings: <the list>, smallest: <cm>, largest: <cm> and average: <cm>. Work the average out with a loop or with sum and len, not by typing numbers.

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

readings = []

Challenges

  1. Find the smallest reading with a loop, without using min.
  2. Drive a shape from a list of [distance, turn] pairs, such as [[30, 90], [20, 90], [30, 90], [20, 90]].
  3. Count how many names in a list start with the letter A.