while loops
Repeat code while a condition holds, read input until a sentinel appears, find bugs in a loop with print debugging, and stop loops that would never end.
What you will learn
- Write a while loop that runs while a condition is true
- Build a sentinel loop that reads input until the user quits
- Use break and continue inside a while loop
- Trace a loop with print debugging, and spot and fix an infinite loop
On this page
A loop repeats a block of code. The fundamentals lesson on repetition explains when to choose a loop that counts and when to choose one that waits for a condition. Python’s while is the second kind: it keeps going while its condition is truthy.
The basic loop
n = 3while n > 0: print(n) n -= 1print("Liftoff")321LiftoffThe loop follows the same shape as if: a condition, a colon, and an indented block. Python checks the condition before every pass, including the first. If it is false from the start, the body never runs. n -= 1 is shorthand for n = n - 1, and the block must change something that the condition depends on, or the loop never ends.
Sentinel loops
Often you do not know how many times to repeat. You keep asking until the user types a special sentinel value. The usual Python shape is while True with a break. break leaves the loop immediately.
This program adds up numbers until the user types nothing and presses Enter:
total = 0count = 0
while True: text = input("Number (blank to stop): ") if text == "": break total += int(text) count += 1
print("Total:", total, "from", count, "numbers")Here the user typed 10, 20 and then just pressed Enter:
Number (blank to stop): 10Number (blank to stop): 20Number (blank to stop):Total: 30 from 2 numberswhile True looks alarming, but it is deliberate: the loop has an exit point in the middle of the body, and it is a break. Writing the input() call once, inside the loop, avoids repeating it before the loop to prime the condition.
continue
continue is the other control word. It skips the rest of the current pass and jumps back to the condition. A guessing game uses it to reject non-numeric input without counting an attempt:
secret = 42attempts = 0
while True: text = input("Guess a number from 1 to 100 (q to quit): ") if text == "q": print("Bye.") break if not text.isdigit(): print("Please type a whole number.") continue attempts += 1 guess = int(text) if guess < secret: print("Too low.") elif guess > secret: print("Too high.") else: print(f"Correct, after {attempts} attempts.") breakHere the typed answers were 50, hello, 25 and 42:
Guess a number from 1 to 100 (q to quit): 50Too high.Guess a number from 1 to 100 (q to quit): helloPlease type a whole number.Guess a number from 1 to 100 (q to quit): 25Too low.Guess a number from 1 to 100 (q to quit): 42Correct, after 3 attempts.Notice that "hello" did not count: the attempts total is 3, not 4. The program has two break exits, one for quitting and one for winning.
Debugging a loop with print
When a loop does something you did not expect, the quickest tool is to print the variables that change on every pass. The = form of an f-string, from the f-strings lesson, prints the name next to the value:
n = 6while n != 1: print(f"{n=}") if n % 2 == 0: n = n // 2 else: n = 3 * n + 1print("reached", n)n=6n=3n=10n=5n=16n=8n=4n=2reached 1Each line shows the value of n at the start of a pass, so you can follow the loop step by step and see where it stops behaving as you expect. Delete the print when you are done.
For longer programs, Python can pause on a line and let you inspect variables interactively. Putting breakpoint() on a line starts the built-in debugger there. A later lesson shows how to use it.
Common pitfalls
- Forgetting to update the loop variable.
while n > 0:with non -= 1runs forever. Stop a runaway program in the terminal with Ctrl+C. - Off-by-one conditions.
while n > 0counts 3, 2, 1.while n >= 0would also print 0. Trace through a small case by hand, or with aprint. - Changing the wrong variable. If you update
countbut the condition teststotal, nothing converges. continuethat skips the update. If the stepn += 1comes after acontinue, the loop can stick on the same value forever. Update before youcontinue.- Comparing floats for equality.
while x != 1.0withx += 0.1may never hit exactly 1.0. Use<or<=.
Predict what this loop prints, then run it. Input: none. Expected output: four lines.
n = 10while n > 0: print(n) n -= 3Show solution
10741After 1 the value becomes -2, which fails the test n > 0, so the loop stops. The loop never prints 0 or a negative number.
Write a program that asks for whole numbers one at a time with the prompt Number (0 to stop): , adds them up, and stops when the user types 0. Then print Total: and the sum.
Input: 5, 3, 8, 0. Expected output: the prompts and then Total: 16.
Show solution
total = 0
while True: number = int(input("Number (0 to stop): ")) if number == 0: break total += number
print("Total:", total)Number (0 to stop): 5Number (0 to stop): 3Number (0 to stop): 8Number (0 to stop): 0Total: 16The 0 is read and converted, then break leaves the loop before it can be added. Adding 0 would not change the total anyway, but the pattern is the same one you would use for any sentinel.
Extend the guessing game. Count how many numeric guesses the player makes, and stop with a message after 7 wrong guesses, revealing the secret. Use a won flag to remember whether the player got it right.
Input: the answers 10, 99, abc, 41, 43, 50, 5 and 60. Expected output: the prompts with Too low. or Too high. after each number, Please type a whole number. for abc, and finally Out of guesses. The number was 42.
Show solution
secret = 42max_attempts = 7attempts = 0won = False
while attempts < max_attempts: text = input("Guess: ") if not text.isdigit(): print("Please type a whole number.") continue attempts += 1 guess = int(text) if guess == secret: print(f"Correct, after {attempts} attempts.") won = True break print("Too low." if guess < secret else "Too high.")
if not won: print(f"Out of guesses. The number was {secret}.")Guess: 10Too low.Guess: 99Too high.Guess: abcPlease type a whole number.Guess: 41Too low.Guess: 43Too high.Guess: 50Too high.Guess: 5Too low.Guess: 60Too high.Out of guesses. The number was 42.The loop condition now enforces the limit, so no while True is needed. The won flag is set just before the break, and the test after the loop reports the failure only when the player never won. The loop control lesson shows a tidier way to do this with an else on the loop.
Summary
while condition:repeats its block as long as the condition is truthy, testing before each pass.while Trueplusbreakis the standard shape for sentinel loops and loops with several exits.breakleaves the loop;continueskips to the next pass. Make sure something in the body moves the loop towards its end, and useprint(f"{x=}")to trace it.
Next: for loops and range.