While Loops
A for loop repeats once for each item in a collection. Sometimes you don't know in advance how many times to repeat. You just want to keep going while something is true: until the user types the right password, until the money runs out, until the game ends. That's what a while loop does.
The while loop
A while loop checks a condition. If it's True, the body runs, and then Python checks the condition again. Once the condition is False, the loop ends.
count = 1
while count <= 5:
print("Count is", count)
count += 1
print("Loop finished")Step by step, Python does this:
Check count <= 5 |
Prints | count becomes |
|---|---|---|
1 <= 5 is True |
Count is 1 | 2 |
2 <= 5 is True |
Count is 2 | 3 |
3 <= 5 is True |
Count is 3 | 4 |
4 <= 5 is True |
Count is 4 | 5 |
5 <= 5 is True |
Count is 5 | 6 |
6 <= 5 is False |
(loop ends) |
Three things make this work:
- A variable is set before the loop (
count = 1). - The condition uses it (
count <= 5). - The body changes it (
count += 1).
The condition is only checked at the start of each pass, not in the middle of the body. And if it's False the very first time (say count = 10), the body runs zero times and Python goes straight to the line after the loop.
Infinite loops
If the condition never becomes False, the loop runs forever. That's called an infinite loop, and it's the most common while bug. Forgetting the count += 1 line above would cause one.
Try this one, and press Stop to end it:
n = 1
while n > 0:
n += 1Tip: If your program seems frozen, check that something inside the loop changes the condition.
Looping until something happens
while shines when the number of repeats depends on the data. How many years does it take for savings to double at 5% interest?
balance = 1000
years = 0
while balance < 2000:
balance *= 1.05
years += 1
print(f"It takes {years} years to reach {balance:.2f}")balance *= 1.05 multiplies the balance by 1.05 each year, which adds 5%. After year 1 it's 1050.00, after year 2 1102.50, and so on. Nobody had to work out the number of years in advance; the loop simply stops on the first check where balance < 2000 is False, after 15 years.
Asking until the input is valid
Keep asking until the user gives an acceptable answer. Run this and try typing a number outside the range first:
rating = int(input("Rate us from 1 to 5: "))
while rating < 1 or rating > 5:
print("Please enter a number between 1 and 5.")
rating = int(input("Rate us from 1 to 5: "))
print(f"Thanks for rating us {rating}!")Notice that the question appears twice. The first input(), before the loop, gets an answer to check. The second, inside the loop, asks again after each wrong answer. Without it, rating would never change, and the loop would repeat forever. A valid answer the first time skips the loop body entirely.
while True with break
Another common style is an endless while True: loop that you leave with break when you're done. while True: means "repeat forever", because the condition can never be False. The only way out is break, which ends the loop immediately and jumps to the first line after it. It's handy when the exit check belongs in the middle of the loop:
total = 0
while True:
entry = input("Enter a number (or 'done'): ")
if entry == "done":
break
total += float(entry)
print(f"Total: {total}")The order inside the loop matters. The if entry == "done" check comes before float(entry), because float("done") would be a ValueError. Each pass: ask, check whether to stop, and only then convert and add.
continue
continue skips the rest of the current pass and jumps back to the condition:
n = 0
while n < 10:
n += 1
if n % 2 == 0:
continue # skip evens
print(n, end=" ")This prints 1 3 5 7 9. Notice where n += 1 is: at the top of the body, before the continue. If it came after the continue, it would be skipped for even numbers, n would get stuck at 2, and the loop would never end. In a while loop, make sure the line that changes the condition can't be skipped.
Going deeper: while ... else optional
Like a for loop, a while loop can have an else block. It runs when the condition becomes false, but not when the loop is left with break. That's handy for "you have a limited number of tries" situations:
attempts = 0
while attempts < 3:
password = input("Password: ")
if password == "python":
print("Welcome!")
break
attempts += 1
else:
print("Too many attempts. Locked out.")Run it twice: once typing python, and once getting it wrong three times. Only the second run reaches the else block.
A while True: loop can only end with break, so an else block after it would never run.
A guessing game
Here's everything together. The random module picks a secret number. random.randint(1, 20) gives a whole number from 1 to 20, and unlike range(), both ends are included:
import random
secret = random.randint(1, 20)
guesses = 0
print("I'm thinking of a number between 1 and 20.")
while True:
guess = int(input("Your guess: "))
guesses += 1
if guess < secret:
print("Too low!")
elif guess > secret:
print("Too high!")
else:
print(f"Correct! You got it in {guesses} guesses.")
breakfor or while?
Use for when… |
Use while when… |
|---|---|
| you're going through every item of a collection | you repeat until a condition changes |
you know how many times to repeat (range) |
you don't know how many repeats you'll need |
| e.g. print each name | e.g. keep asking until the answer is valid |
If you can write it as a for loop, that's usually simpler and safer, because a for loop can't run forever by accident.
Exercises
Exercise 1: Powers of two
Use a while loop to print every power of 2 that is less than 1000: 1 2 4 8 ... 512.
power = 1
Loop while power < 1000: and double power each time with power *= 2.
Print with end=" " to keep all the numbers on one line.
Exercise 2: Digit sum
Add up the digits of number using a while loop, % 10 (last digit) and // 10 (remove the last digit). For 4719 it should print 21.
number = 4719 total = 0
number % 10 is the last digit, and number // 10 removes it.
Repeat while number > 0, adding each last digit to total.
Exercise 3: Password check
Keep asking for the password until the user types python123, then print Access granted. Allow at most 3 attempts. After 3 wrong attempts, print Account locked.
attempts = 0
Count the attempts: loop while attempts < 3 and add 1 each time.
Use break when the password is right. A loop's else block runs only if the loop ended without break.
The else on a loop runs only if the loop finished without hitting break. It's a neat trick for "searched everything, didn't find it" situations.
Exercise 4: Fix the infinite loop
This loop is meant to print 10, 8, 6, 4, 2, but it never stops. Press Run, then Stop, and fix it.
n = 10
while n != 0:
print(n)
n -= 3Watch the output: 10, 7, 4, 1, -2... n jumps over 0, so n != 0 stays true forever.
Count down in steps of 2, and loop while n > 0 so the loop stops even if it skips past 0.
Summary
while condition:repeats the body as long as the condition is true.- Something inside the loop must eventually make the condition false, or the loop runs forever.
whileis ideal when you don't know the number of repeats in advance, such as input validation or games.while True:withbreakexits from the middle of a loop.continueskips to the next pass.- Prefer
forwhen you're going through a collection or a fixed range.
Know something worth teaching? Write your own tutorial with runnable examples and share it.