while
The condition is re-checked before every pass. Nothing changes it for you — if the body never makes it false (or breaks), the loop runs forever.
while condition: body
while condition: body # may break else: no_break # condition went false
while True: step if done: break
Demo
n = 100 steps = [] while n > 0: steps.append(n) n //= 2 steps
In the while tab, 0 and negative numbers give an empty list: the test n > 0 is false before the first pass, so the body never runs. In the while / else tab, 0 and 5 never match an attempt, the condition attempts < 3 goes false, and else runs; any break jumps past it. In the while True tab, the loop only ends at "stop" — with no stop item, the loop keeps popping until the list is empty and pop raises IndexError, which is how an unguarded while True fails when the exit never comes.
Syntax slots
| Name | Type | Required | Description |
|---|---|---|---|
| condition | expression | yes | Evaluated before each iteration, truthiness rules as in if. False on the first check → the body never runs. |
| body | block | yes | Must eventually make the condition false, or leave with break / return / an exception. |
| else | block | no | Runs once when the condition turns false — skipped if the loop was left with break. |
Common patterns
from collections import deque def drain(queue: deque): while queue: item = queue.popleft() print(item)
def read_chunks(f, size=4096): while True: chunk = f.read(size) if not chunk: break yield chunk
def read_chunks(f, size=4096): while (chunk := f.read(size)): yield chunk
def fetch(try_once, attempts=3): while attempts > 0: attempts -= 1 if (result := try_once()) is not None: break else: raise TimeoutError("no result") return result
Examples
Pitfalls
items = ['a', 'b', 'c'] i = 0 while i <= len(items): print(items[i]) i += 1
items = ['a', 'b', 'c'] i = 0 while i < len(items): print(items[i]) i += 1
x = 0.0 steps = 0 while x != 1.0: x += 0.1 steps += 1 if steps == 50: # safety cap break (steps, x)
steps = 0 while steps < 10: steps += 1 x = steps / 10 (steps, x)
i = 0 seen = [] passes = 0 while i < 4: passes += 1 if passes > 10: # safety cap break if i == 2: continue seen.append(i) i += 1 (seen, i)
i = 0 seen = [] while i < 4: i += 1 if i == 2: continue seen.append(i) seen
names = ['Ann', 'Bo'] i = 0 out = [] while i < len(names): out.append(names[i].upper()) i += 1 out
names = ['Ann', 'Bo'] out = [] for name in names: out.append(name.upper()) out
When to use
- Repeating until a condition changes — input is valid, a queue is empty, a value converges
- Loops where the number of passes is not known in advance
- Event / retry loops written as while True with break
- Walking the items of a list, string, dict or file → for
- Counting a fixed number of times → for i in range(n)
- Waiting for time to pass in a busy loop → time.sleep or an event
Notes
FAQ
In code: give it an exit — a condition that the body eventually makes false, or a break. At the terminal: Ctrl+C raises KeyboardInterrupt and ends the program (unless the loop catches it with a bare except, which is one more reason not to write those).