Programming Fundamentals
Iteration is the programming construct where a set of instructions is repeated. Along with sequence (steps carried out in order) and selection (choosing between different paths), it is one of the three basic constructs.
A count-controlled loop runs its body a set number of times. That number is already known before the loop begins. The number can be a fixed value written in the program, a variable holding a value worked out earlier, or input typed by the user. In Python, a for loop with range() is a count-controlled loop.
The loop body is the code that repeats. It runs once for every value taken by the loop variable, so the loop variable changes on each pass. The repeated lines under the for line form the loop body.
This program prints the lap number for each of four laps:
for lap in range(1, 5):
print("Lap " + str(lap))Output:
Lap 1
Lap 2
Lap 3
Lap 4
The loop body runs four times, with lap holding 1, then 2, then 3, then 4. Each pass prints one line showing the current lap.
Choose a count-controlled loop when you know before the loop starts how many passes are needed, such as printing 8 tickets or asking 5 questions. If you cannot tell how many passes will be needed before the loop starts, use a condition-controlled loop instead.
In a range(), you don't have to give all the values. A single value does two jobs at once: it becomes the stop, and the start is set to 0. So range(6) is the same as range(0, 6), and both count 0, 1, 2, 3, 4, 5 with a step of 1.
Because the stop is never included, a loop that should finish on a particular number must stop one beyond it. To count up by one through 1 to 6, write range(1, 7). The loop keeps running while the next value is still on the start's side of the stop, and ends as soon as the next value would land on the stop or go past it.
A third value is the step: how much the loop variable changes each time. A positive step counts up, a negative step counts down. A step of 0 is not allowed, because the loop variable would never move towards the stop, so Python reports an error instead of running the loop.
| Range | Values taken |
|---|---|
range(3) | 0, 1, 2 |
range(4, 10, 3) | 4, 7 |
range(9, 2, -2) | 9, 7, 5, 3 |
range(7, 7) | none |
In the third row the step is negative, so the stop must be less than the start for anything to happen. If you wrote range(3, 9, -2) the first value is already below the stop and no values are produced. A range that produces no values is not an error: the loop body is simply skipped and the program carries on with the next line.
for shelf in range(1, 5):
print("Checking shelf", shelf)
print("All shelves checked")Output:
Checking shelf 1
Checking shelf 2
Checking shelf 3
Checking shelf 4
All shelves checkedThe loop above runs four times, with shelf taking the values 1, 2, 3 and 4. The value 5 is the stop, so it is never used. The last message sits outside the loop, so it runs once, after every shelf has been checked.
The loop variable is the variable named in a for line, such as day in for day in range(1, 5):. It holds a different value on each pass — 1, then 2, then 3, then 4 — so anything you do with it inside the loop can change each time. That is what makes count-controlled loops useful for repeating work a set number of times, instead of writing the same instruction out again and again.
Because the loop variable changes, you can drop it into a calculation or a message. Printing "Lap " + str(lap) inside a training loop labels every lap for you, and printing str(canteens * 6) tells you how many pupils can be seated once that many six-seat canteen tables are full. The calculation is written once, but the answer is different on every pass.
Here the loop variable form numbers each prompt, and each amount is added to a running total:
total = 0
for form in range(1, 4):
raised = int(input("Amount raised by form " + str(form) + ": "))
total = total + raised
print("Total raised: " + str(total))
print("Average per form: " + str(total / 3))Output when the user types 25, 40, 55:
Amount raised by form 1: 25
Amount raised by form 2: 40
Amount raised by form 3: 55
Total raised: 120
Average per form: 40.0
A running total is built up one value at a time. Set it to zero before the loop, then add each new value inside the loop with a line such as total = total + raised. Three form groups raising 25, 40 and 55 give:
| Pass (form) | raised entered | total after the line |
|---|---|---|
| 1 | 25 | 25 |
| 2 | 40 | 65 |
| 3 | 55 | 120 |
An average can only be found once every value has been added, so the division belongs after the loop: 120 divided by 3 gives 40.0. Dividing inside the loop would only average the amounts collected so far, which is not the average of all three.
Putting total = 0 inside the loop instead of before it causes a logic error, because the total is wiped clean on every pass. It would end up holding only the last amount entered — 55 — so the total and the average would both be wrong.
A for loop can take its values straight from a sequence — an ordered collection of items, such as the characters in a string — instead of counting through a range. Each pass gives the loop variable the next item in turn, so you never mention a position at all. The loop still repeats a set number of times: once for every item, so it is count-controlled iteration.
In the program below the loop runs once for every character in the combination, and digit holds a different character on each pass. The number of passes is decided automatically by how many characters the combination has, so you cannot get the count wrong.
combination = "8362"
for digit in combination:
print("Turn to " + digit)Output:
Turn to 8
Turn to 3
Turn to 6
Turn to 2
Iterating over the items is shorter and easier to read, so use it whenever each item is all you need: printing it, using it in a calculation, or testing it with an if. What you give up is any knowledge of where the item came from, because the loop never hands you its index.
When the position matters, write range(0, len(sequence)) instead. The loop variable then holds an index, counting 0 up to one less than the length, and you use that index to reach into the sequence. To compare the characters in matching places in two words, both words must be read with the same index at the same moment, and counting with range keeps them in step in a way the item-only loop cannot.
| What you write | Loop variable holds | Use it when |
|---|---|---|
for item in sequence: | each item in turn | you only need the item itself |
for i in range(0, len(sequence)): | each position, 0 to length - 1 | you need the position, or must match positions across sequences |