Python while Loops: Condition-Driven Repetition and Infinite Loop Safety
A for loop iterates over a known collection of items. A while loop repeats as long as a condition stays True. Use while when you do not know in advance how many iterations you will need — when the stopping point depends on something that changes during execution.
Basic Syntax and Mechanics
count = 0
while count < 5: print(count) count += 1
# 0# 1# 2# 3# 4Before each iteration, Python evaluates the condition (count < 5). If it’s True, the body runs. If it’s False, the loop exits. If the condition is False from the start, the body never runs.
The condition must evaluate to a boolean — or any truthy/falsy value.
The Infinite Loop Risk
The most common while loop bug is a loop that never terminates because the condition never becomes False.
# Bug: count is never incrementedcount = 0while count < 5: print(count) # forgot: count += 1This runs forever (or until you press Ctrl+C). Before writing a while loop, always ask: what changes inside the loop that will eventually make the condition False?
while True with break: Explicit Exit Control
Sometimes you want the exit condition to be checked somewhere in the middle of the loop rather than at the top. The pattern is while True: combined with break:
def get_positive_number(): while True: raw = input("Enter a positive number: ") try: value = float(raw) if value > 0: return value print("Must be greater than zero — try again") except ValueError: print("That's not a number — try again")
n = get_positive_number()print(f"Got: {n}")This is the idiomatic Python equivalent of a “do-while” loop (which Python does not have as a keyword). The body always runs at least once because the condition check happens partway through.
Sentinel Values
A sentinel value is a special value used to signal the end of input or processing. The loop continues until it receives the sentinel.
total = 0count = 0
print("Enter numbers to average. Type 'done' when finished.")while True: entry = input("> ") if entry.lower() == "done": break try: total += float(entry) count += 1 except ValueError: print("Not a number, skipping")
if count > 0: print(f"Average: {total / count:.2f}")else: print("No numbers entered")Here, "done" is the sentinel — it is not real data, just the signal to stop.
Retrying with a Limit
A common pattern is retrying an operation that might fail, but giving up after a certain number of attempts.
import random
def unreliable_fetch(): """Simulates a network call that fails 70% of the time.""" return random.random() > 0.7
max_retries = 5attempt = 0success = False
while attempt < max_retries: attempt += 1 print(f"Attempt {attempt}...") if unreliable_fetch(): success = True break print(" Failed, retrying...")
if success: print("Fetch succeeded")else: print(f"Failed after {max_retries} attempts")This is a better pattern than an infinite retry loop — it guarantees termination.
while/else
Just like for loops, while loops support an else clause that runs only if the loop exits normally (not via break).
target = 7guess = 0
while guess != target: guess = int(input("Guess (1-10): ")) if guess == target: print("Correct!") breakelse: # This branch would run if the condition became False without a break # In this example, that cannot happen, but here is the pattern print("Condition became False without breaking")A more natural use of while/else:
attempts = 3correct_pin = "1234"
while attempts > 0: pin = input("Enter PIN: ") attempts -= 1 if pin == correct_pin: print("Access granted") break print(f"Wrong PIN. {attempts} attempt(s) remaining.")else: print("Account locked — too many incorrect attempts")The else block runs only if the loop exhausted all attempts without finding the correct PIN.
Processing Streams and Queues
while loops are natural for processing data that arrives continuously — reading from a queue, consuming a stream, polling a sensor.
from collections import deque
queue = deque(["task1", "task2", "task3"])
while queue: task = queue.popleft() print(f"Processing: {task}") # Add new tasks conditionally if task == "task2": queue.append("task4")
# Processing: task1# Processing: task2# Processing: task3# Processing: task4while queue: is truthy as long as the deque is non-empty — Python evaluates its __bool__() method.
Comparing while to for
for | while | |
|---|---|---|
| Iteration type | Over a sequence or iterable | Condition-based |
| Iteration count | Usually known | Often unknown |
| Risk of infinite loop | Low | Higher |
| Best for | Collections, ranges, sequences | Input validation, polling, retries, streams |
When you know the collection upfront, prefer for. Use while when the termination depends on something that changes unpredictably.
Common Mistakes
Not modifying the condition variable. Every while loop must change something that the condition depends on, or it will loop forever.
Off-by-one errors. while count <= 5 runs 6 times (0 through 5). while count < 5 runs 5 times. Trace through the first and last iteration by hand when in doubt.
Using while True without a reachable break. If the break is inside a conditional that can never be true, you have an infinite loop again.
Confusing continue and break. continue skips the rest of the current iteration and re-evaluates the condition. break exits the loop entirely. Mixing them up produces incorrect loop behaviour without any obvious error.