while Loops

A while loop repeats a block as long as a condition stays true. It's the right loop when you don't know in advance how many repetitions you'll need — keep asking until the answer is valid, keep retrying until it works, keep simulating until a target is reached.

Basic while loop

PY while.py
count = 1

while count <= 5:
    print("Count is", count)
    count += 1

print("Done")
Output
Count is 1
Count is 2
Count is 3
Count is 4
Count is 5
Done

The condition is checked before each pass. Something inside the loop must eventually make it false — here, count += 1.

Looping until a goal

PY savings.py
balance = 1000
rate = 0.07
years = 0

while balance < 2000:
    balance *= 1 + rate
    years += 1

print(f"Doubled after {years} years: ${balance:,.2f}")
Output
Doubled after 11 years: $2,104.85

Infinite loops and break

A common pattern is while True with a break inside, when the exit condition is easiest to check in the middle of the loop:

PY break.py
attempts = ["", "abc", "42"]

while True:
    text = attempts.pop(0)
    print(f"Got {text!r}")
    if text.isdigit():
        number = int(text)
        break
    print("  not a number, asking again")

print("Accepted", number)
Output
Got ''
  not a number, asking again
Got 'abc'
  not a number, asking again
Got '42'
Accepted 42

In a real program, attempts.pop(0) would be input("Enter a number: "). If a loop accidentally never ends, stop the program with Ctrl+C in the terminal.

continue

continue skips the rest of the current pass and goes back to the condition:

PY continue.py
n = 0
while n < 10:
    n += 1
    if n % 3 != 0:
        continue
    print(n, "is divisible by 3")
Output
3 is divisible by 3
6 is divisible by 3
9 is divisible by 3

Note the increment happens before continue; putting it after would skip it and loop forever.

Looping while a collection has items

PY queue.py
tasks = ["write", "test", "deploy"]

while tasks:
    task = tasks.pop(0)
    print("Doing", task, "-", len(tasks), "left")
Output
Doing write - 2 left
Doing test - 1 left
Doing deploy - 0 left

An empty list is falsy, so while tasks: stops once everything has been processed. (For large queues, collections.deque is faster at removing from the front — lesson 27.)

The walrus operator in loops

PY walrus.py
chunks = iter(["alpha", "beta", ""])

while (chunk := next(chunks)) != "":
    print("Processing", chunk)
Output
Processing alpha
Processing beta

:= assigns and tests in one step — common when reading data in chunks until an empty one arrives.

A classic algorithm

Euclid's algorithm finds the greatest common divisor of two numbers with a simple while loop:

PY gcd.py
def gcd(a, b):
    while b:
        a, b = b, a % b
    return a

print(gcd(48, 18), gcd(17, 5), gcd(100, 75))
Output
6 1 25

(The standard library has math.gcd for real use.)

while or for?

If you're stepping through a sequence or a known range of numbers, use a for loop (next lesson) — it can't accidentally loop forever and there's no counter to manage. Use while when the number of repetitions depends on something that happens inside the loop.

Try it yourself

Try it yourself
Console output