Loops: for and while
Repetition done properly, including nested loops, break and continue, and how to avoid the infinite loop that eats your afternoon.
for loops
A for loop repeats once for each item in a collection.
for i in range(5):
print(i) # 0 1 2 3 4range
range(5) # 0, 1, 2, 3, 4
range(2, 6) # 2, 3, 4, 5
range(0, 10, 2) # 0, 2, 4, 6, 8
range(10, 0, -1) # 10, 9, 8 ... 1range(1, 6) gives 1 to 5. This is the source of most off by one errors.
Looping over other things
for name in ["Aisha", "Ben", "Chloe"]:
print("Hello,", name)
for letter in "Python":
print(letter)
for index, name in enumerate(["a", "b", "c"]):
print(index, name) # 0 a, 1 b, 2 cNested loops
for row in range(3):
for col in range(4):
print("*", end=" ")
print()The inner loop completes fully for every single iteration of the outer loop, so this prints twelve stars in three rows of four.
- for repeats a set number of times. range(5) gives 0, 1, 2, 3, 4: five laps.
- while repeats until its condition is False, checked before every go round.
while loops
A while loop repeats for as long as a condition is true. Use it when you do not know how many repetitions are needed.
total = 0
number = int(input("Enter a number, 0 to stop: "))
while number != 0:
total += number
number = int(input("Enter a number, 0 to stop: "))
print("Total:", total)Infinite loops
count = 0
while count < 10:
print(count) # count never changes, so this never endsThe fix is count += 1 inside the loop. Always check that something inside the loop changes the value being tested.
Press Ctrl and C to stop a runaway program.
break and continue
while True:
command = input("Command: ")
if command == "quit":
break # leave the loop immediately
if command == "":
continue # skip the rest of this iteration
print("You typed", command)while True with a break is a common and readable pattern for menus and validation.
Known number of repetitions, or looping over a collection, means for. Unknown number, depending on something that happens while running, means while.
- for repeats a counted number of times and stops by itself.
- while checks a condition each time and repeats until it is false.
- If nothing inside the loop changes the condition, the loop never stops.
Loops in practice
Running totals and counters
numbers = [4, 8, 15, 16, 23, 42]
total = 0
count_over_10 = 0
for n in numbers:
total += n
if n > 10:
count_over_10 += 1
print("Total:", total)
print("Average:", total / len(numbers))
print("Over ten:", count_over_10)Finding a maximum
highest = numbers[0] # start from the first item, never from 0
for n in numbers:
if n > highest:
highest = n
print("Highest:", highest)If every value is negative, nothing is ever greater than 0 and the answer will be wrong. Start from the first element.
Validation
while True:
entry = input("Enter a mark between 0 and 100: ")
if entry.isdigit() and 0 <= int(entry) <= 100:
mark = int(entry)
break
print("That is not a valid mark.")Building a times table
number = int(input("Which table? "))
for i in range(1, 13):
print(number, "x", i, "=", number * i)A simple menu
while True:
print("\n1. Add 2. View 3. Quit")
choice = input("Choose: ")
if choice == "1":
print("Adding...")
elif choice == "2":
print("Viewing...")
elif choice == "3":
print("Goodbye")
break
else:
print("Please choose 1, 2 or 3.")Key terms you must be able to define
- for loop
- A loop that repeats once for each item in a collection or range.
- while loop
- A loop that repeats for as long as its condition remains true.
- range()
- A function producing a sequence of numbers for a for loop to work through.
- Nested loop
- A loop placed inside another loop.
- Infinite loop
- A loop whose condition never becomes false, so it never ends.
- break
- A statement that leaves a loop immediately.
- continue
- A statement that skips the rest of the current iteration and starts the next.
- Iteration
- One single pass through the body of a loop.
Flashcards
Say the definition out loud before you flip the card. Retrieving it from memory is what builds recall, reading it again is not.
Reach the top grade on this topic
- Choose for or while correctly and be able to justify the choice
- Write a validation loop that keeps asking until the input is acceptable
- Trace a nested loop and state exactly how many times the inner body runs
- Initialise a maximum from the first element of the data, never from zero
- Check every while loop for something that changes the condition
Mistakes that cost marks here
- Assuming range(5) includes 5.
- Writing a while loop where nothing inside changes the condition.
- Initialising a maximum to 0 when the data could be negative.
- Using a for loop when the number of repetitions is not known in advance.
- Putting code that should run once inside the loop, so it runs every time.
A nested loop with 1000 iterations on each level runs its inner body one million times. This is why an algorithm that seems fine on ten items can freeze completely on ten thousand.
Knowledge check
for i in range(6) repeat?range(2, 8) produce?break do?continue do?for letter in "cat" loop over?enumerate() give you?Exam-style questions
Five written questions in the style of the real paper. Write a full answer, then let the marker check it against the mark scheme.
- LA for loop repeats a known number of times or over a collection
- LSituation such as processing every item in a list
- LA while loop repeats while a condition is true
- LSituation such as validating input until it is correct
A for loop repeats a known number of times, or once for each item in a collection, so the number of iterations is decided before the loop begins. It would be used to work through every mark in a list of 30 students, because the number of repetitions is known from the length of the list. A while loop repeats for as long as its condition remains true, so the number of iterations is not known in advance and depends on what happens while the program is running. It would be used to keep asking a user to enter a valid password until they get it right, since there is no way to know how many attempts they will need.
- LInitialises a total and a counter
- LUses a while loop
- LReads and converts input inside the loop
- LStops when -1 is entered without counting it
- LPrints the count and total after the loop
total = 0 count = 0 number = int(input("Enter a number, -1 to finish: ")) while number != -1: total += number count += 1 number = int(input("Enter a number, -1 to finish: ")) print("You entered", count, "numbers") print("Their total is", total) The first number is read before the loop so the condition has something to test. The loop continues while the number is not -1, adding to the total and increasing the counter each time before reading the next value. Because the read happens at the end of the loop body, the -1 that ends the loop is never counted or added.
- LThe condition never becomes false
- LBecause nothing inside the loop changes the value being tested
- LPrevent it by ensuring the loop body updates the variable in the condition
An infinite loop happens when the condition a while loop tests never becomes false, so the loop has no way to end. This is almost always because nothing inside the loop body changes the value that the condition depends on, for example writing while count is less than 10 but never increasing count. It can also happen when the change moves the value in the wrong direction. To prevent it, always check that the loop body contains a statement that alters the variable in the condition, and that it alters it in a direction that will eventually make the condition false.
- LThe inner body runs 24 times
- LThe inner loop completes fully for each outer iteration
- LSo the totals are multiplied together
The inner loop body executes 24 times in total. Each time the outer loop runs one iteration, the inner loop starts from the beginning and completes all six of its own iterations before control returns to the outer loop. Since the outer loop repeats four times, the inner body runs six times on each of those four occasions, and 4 multiplied by 6 gives 24. This multiplication is why nested loops become expensive very quickly on large amounts of data.
- LInitialises the largest to the first element of the list
- LLoops through every item in the list
- LCompares each item with the current largest
- LUpdates the largest when a bigger value is found and prints the result
numbers = [12, -5, 33, 8, -47, 21] largest = numbers[0] for n in numbers: if n > largest: largest = n print("The largest number is", largest) The variable largest is initialised to the first element of the list rather than to 0, which matters because the list contains negative numbers and initialising to 0 would give a wrong answer if every value were negative. The loop then compares each value with the current largest and replaces it whenever a bigger one is found, so after the loop finishes largest holds the maximum.