While loops
Repeat until something changes: goals reached, answers valid, tasks done.
Why it matters
A for loop works through a list you already have. Plenty of jobs aren't like that: retry until the server answers, ask until the reply makes sense, keep going until the goal is reached. An AI agent is exactly this kind of loop. It asks a model what to do next, does it, and stops only when the task is finished. That loop is a while loop, and you'll write one in Phase 1.
What you'll be able to do
- Write a while loop that repeats until its condition becomes false
- End a loop early with break, or keep it running with while True
- Ask the user again until their answer is valid
- Spot a loop that never ends, and fix it
What it covers
- When you can't count the repeats
- A robot in a stockroom
- Crates in the way
- Stop when you're done: break
- Guess the number
- Loops that never end
- Worked example: climbing piles of crates
- Choosing between for and while
When you can't count the repeats
A for loop runs once for each item in a list. You know in advance how many times that is.
Often you don't. You stir a sauce until it thickens. You keep a kettle on until it boils. You don't count the stirs; you check a condition and stop when it changes.
A while loop works the same way. It checks a condition, runs its body if the condition is true, then checks again. It stops the first time the condition is false:
savings = 0 weeks = 0 while savings < 500: savings = savings + 60 weeks = weeks + 1 print("weeks needed:", weeks) print("saved:", savings)
Read it as "while savings are under 500, save another 60 and count a week". After 8 weeks the savings reach 480, still under 500, so the loop runs once more. After week 9 the savings are 540, the condition is false, and Python moves on to the print lines.
Two things must be true for a while loop to work:
- something inside the loop changes what the condition looks at, here
savings; - that change eventually makes the condition false.
Each box takes 3 items. Step through and watch the condition on line 3 checked before every pass, including the last check, which is false and ends the loop.
n = 1 while n < 20: n = n * 3 print(n)
Show the answer
27
n goes 1, 3, 9, 27. When n is 9 the condition is true, so it becomes 27. Then 27 < 20 is false and the loop stops.
A robot in a stockroom
To practice, you'll steer a robot. It works in a stockroom laid out as a grid of squares. It can do two things: move() one square forward, and turn_left(). It can also look: front_is_clear() is True when the square ahead is free, and at_goal() is True on the packing bay, the green square.
world("hall") picks an empty aisle. The robot starts on the left, facing east. You could count the squares and write a for loop. But a while loop works in any aisle, however long:
from robot import * world("hall") while not at_goal(): move() print("arrived")
The map under the output shows the path the robot took. not flips True and False, so while not at_goal() reads "while the robot isn't at the bay yet".
The robot only has turn_left. To turn right, it turns left three times. That's a job for a function you write once and reuse, as you saw in the functions lesson:
def turn_right(): turn_left() turn_left() turn_left()
Crates in the way
In world("crates-random"), crates sit on the floor in different places every run. Each one is a single square high. To get over one, the robot goes up, across two squares and back down. That's another function, built from the robot's two moves and your turn_right:
from robot import * def turn_right(): turn_left() turn_left() turn_left() def jump(): turn_left() move() turn_right() move() move() turn_right() move() turn_left() world("crates-random") while not at_goal(): if front_is_clear(): move() else: jump()
Run it a few times. The crates move, and the same code still reaches the bay, because it decides each step by looking. That's the real strength of a while loop with a condition inside: the code reacts to what it finds, instead of following a fixed count.
move() run?while not at_goal(): move()
Show the answer
3
The condition is checked before each move. After the third move the robot is on the bay, not at_goal() is false, and the loop ends without a fourth move.
Stop when you're done: break
Sometimes the natural place to decide is in the middle of the loop. while True repeats forever, and break jumps out of the loop the moment you ask it to.
That's the shape of every "ask until the answer is valid" loop. The program asks with input(), which waits for you to type an answer and press Enter. It always gives back text:
while True: answer = input("How many tents? ") if answer.isdigit() and int(answer) > 0: tents = int(answer) break print("Please type a whole number above 0.") print("Booking", tents, "tents")
Try typing lots, then -2, then 4. isdigit() is True only when every character is a digit, so int(answer) can't fail. The loop keeps asking until the answer passes, then break ends it and the program carries on below.
continue is break's partner. It skips the rest of this pass and goes straight back to the condition. Both work in for loops too.
Guess the number
secret is 42. Ask input("Guess: ") again and again. After a wrong guess, print Higher or Lower. When the guess is right, print Got it in N tries (with the number of guesses) and stop. You can play it with Run.
secret = 42 tries = 0 # Ask until the guess is right
Loops that never end
A while loop whose condition never becomes false runs forever. That's an infinite loop, and everyone writes one sooner or later. Here are the usual causes:
- Nothing changes.
while count < 10:with nocount = count + 1inside. - The change goes the wrong way. Counting down when the condition waits for a count to go up.
- The change is out of the loop. The line that updates the variable isn't indented, so it runs once, after a loop that never finishes.
while Truewith no reachablebreak.
When it happens here, the academy stops your code after a few seconds and says so. The robot stops on its own after 1,000 steps. On your own computer, press Ctrl+C in the terminal.
A good habit before you run a while loop: point at the line that changes the condition, and ask yourself whether that change can reach the stopping point.
Show the answer
n = 1 then while n != 10: n = n + 2
n goes 1, 3, 5, 7, 9, 11, ... and skips 10, so n != 10 is always true. Prefer < or > to != when a step could jump past the stopping value.
Worked example: climbing piles of crates
In world("stacks") the crates come in piles of different heights. The robot climbs up the near side until the square on its right is free, crosses the top, and climbs down until the floor stops it.
from robot import * def turn_right(): turn_left() turn_left() turn_left() def climb_over(): turn_left() while not right_is_clear(): move() turn_right() move() move() turn_right() while front_is_clear(): move() turn_left() world("stacks") while not at_goal(): if front_is_clear(): move() else: climb_over()
There are three while loops, each with its own question. The outer one asks "am I at the bay yet?". Inside climb_over, the first asks "is there still crate on my right?" and the second asks "is there still floor below me?". None of them needs to know how tall a pile is. Each one keeps going until the robot can see the answer, so the same code handles a pile of one or three.
Choosing between for and while
- Use for when you have the items, or know the count: every row in a file, 10 attempts, each day of the week.
- Use while when you stop because something changed: the goal is reached, the answer is valid, the money has run out.
When you can write it either way, for is usually safer. It can't run forever, because it runs out of items.
Practice what you just read
- 6 code examples you can edit and run
- a practice exercise that checks your code
- a 5-question quiz
- 4 review cards for spaced repetition
Try a quiz question
Which job suits a while loop better than a for loop?