Python While Loop

A while loop repeats a block of code for as long as a given condition stays True. Unlike a for loop, which iterates over a known sequence, a while loop is driven purely by a condition — making it the right tool when you don’t know in advance how many times you need to repeat something, such as waiting for user input to be valid or processing data until a sentinel value appears.

Overview / How It Works

Every while loop in Python is built around a boolean expression called the loop condition. Before each pass through the loop body (each iteration), Python evaluates this condition. If it evaluates to True (or any value considered “truthy”), the indented block underneath runs. If it evaluates to False (or “falsy”), Python skips the block entirely and moves on to whatever code comes after the loop.

Internally, there is no magic here: Python re-evaluates the exact same expression object each time through the loop. It does not “remember” the condition’s previous result — it re-runs the comparison or function call from scratch on every pass. This is why the variables involved in the condition must actually change somewhere inside the loop body; otherwise the condition’s truth value never changes, and you get an infinite loop.

Because the condition can be any expression that Python can convert to a boolean, you can loop on numeric comparisons (count < 10), on a variable’s truthiness (while items:, which keeps looping as long as the list items is non-empty), or a function call that returns True/False. Python evaluates truthiness using the same rules as an if statement: 0, 0.0, empty strings, empty containers, and None are falsy; nearly everything else is truthy.

A while loop can also carry an optional else clause. The code in the else block runs once, automatically, right after the loop condition finally becomes False — but only if the loop was never exited early via break. This makes while...else useful for “search and report” patterns, where the else block signals that the search completed without finding what it was looking for.

Syntax

while condition:
    # loop body — runs repeatedly while condition is True
    statement(s)
else:
    # optional — runs once when condition becomes False
    # (skipped if the loop exits via break)
    statement(s)
Part Meaning
while Keyword that starts the loop.
condition Any expression evaluated for truthiness before each iteration. Must not end with a colon-less syntax — Python requires the trailing :.
indented body The statements that repeat. Indentation (typically 4 spaces) defines what belongs to the loop.
break Immediately exits the loop, skipping any else clause.
continue Skips the rest of the current iteration and re-checks the condition.
else Optional block that runs once, only if the loop finished normally (condition became falsy, no break occurred).

Examples

Example 1: Basic counting loop

count = 1
while count <= 5:
    print(f"Count is {count}")
    count += 1

print("Loop finished")
Count is 1
Count is 2
Count is 3
Count is 4
Count is 5
Loop finished

Python checks count <= 5 before each pass. The body prints the current value and then increments count with count += 1. Once count becomes 6, the condition is False, the loop ends, and execution falls through to the print statement after the loop.

Example 2: Using break and continue with user-style input processing

readings = [12, 45, -1, 30, 8, -1, 99]
index = 0
total = 0

while index < len(readings):
    value = readings[index]
    index += 1

    if value == -1:
        # -1 marks a sensor error; skip it but keep going
        continue

    if value > 90:
        # a reading this high means stop processing immediately
        print(f"Critical reading {value} detected, stopping.")
        break

    total += value

print(f"Sum of valid readings processed: {total}")
Critical reading 99 detected, stopping.
Sum of valid readings processed: 95

This simulates reading sensor data one value at a time. continue skips error readings (-1) without adding them to the total. When a reading exceeds 90, break stops the loop entirely — note that the final 99 is never added to total because break happens before total += value. The valid readings summed before the break are 12 + 45 + 30 + 8 = 95.

Example 3: while…else for a search pattern

def find_first_prime_over(n: int) -> int | None:
    candidate = n + 1
    found = None

    while candidate < n + 20:
        is_prime = candidate > 1
        divisor = 2
        while divisor * divisor <= candidate:
            if candidate % divisor == 0:
                is_prime = False
                break
            divisor += 1
        else:
            pass  # inner while's else — not used here, just illustrating scope

        if is_prime:
            found = candidate
            break
        candidate += 1
    else:
        print("No prime found in range")

    return found

result = find_first_prime_over(20)
print(f"First prime after 20: {result}")
First prime after 20: 23

This example nests two while loops: the outer loop searches candidate numbers, and the inner loop tests each candidate for primality by trial division. If the outer loop runs to completion without a break (meaning no prime was found in range), its else block prints a message. Since 23 is prime and found via break, the outer else is skipped, and the function returns 23.

Under the Hood

Step by step, Python executes a while statement like this:

  1. Evaluate the condition expression.
  2. If the result is falsy, skip to step 5 (or run the else block first, if present).
  3. If the result is truthy, execute every statement in the indented body, top to bottom.
  4. After the body finishes (or a continue is hit), jump back to step 1.
  5. If a break is executed at any point inside the body, immediately exit the loop, skipping the else block entirely, and continue with the code after the loop.

A subtle but important detail: the condition expression is not compiled into some special “watcher” — it is ordinary bytecode that re-runs at the top of every iteration. This is why mutating a variable used in the condition (like incrementing a counter, or popping items off a list) is what makes the loop eventually stop. If nothing inside the body ever changes a value that the condition depends on, the loop runs forever (an infinite loop), which is sometimes intentional (e.g. while True: combined with an internal break) but is usually a bug.

Common Mistakes

Mistake 1: Forgetting to update the loop variable

Writing a condition that depends on a variable, but never changing that variable inside the body, creates an infinite loop:

count = 0
while count < 5:
    print(count)
    # forgot count += 1 here — this never terminates

The fix is to make sure every code path through the loop body eventually moves the condition toward False:

count = 0
while count < 5:
    print(count)
    count += 1

Mistake 2: Using assignment (=) instead of comparison (==)

Python actually protects you here more than some languages do — writing while x = 5: is a SyntaxError in Python, because = is a statement, not an expression, and cannot appear inside a condition. If you see this error, replace = with == for comparison, or consider whether you meant to use the walrus operator := for assignment-within-expression, e.g. while (line := next_input()) != "quit":.

Mistake 3: Off-by-one errors in the condition

Using <= when you meant < (or vice versa) is a frequent source of bugs, especially when looping over indices:

data = [10, 20, 30]
index = 0
while index <= len(data):  # bug: should be <
    print(data[index])
    index += 1

This raises an IndexError because len(data) is 3, and data[3] is out of range for a list with valid indices 0, 1, 2. The fix:

data = [10, 20, 30]
index = 0
while index < len(data):
    print(data[index])
    index += 1

Best Practices

  • Prefer a for loop over range() or an iterable whenever you’re iterating a known, fixed number of times — reserve while for cases where the stopping condition truly depends on runtime state.
  • Always make sure at least one statement inside the loop body moves the condition toward becoming False.
  • Use while True: with an explicit break when the natural exit condition is easiest to check in the middle of the loop body (e.g. validating input), rather than contorting the condition to appear at the top.
  • Use the walrus operator := to combine assignment and condition-checking cleanly, e.g. while (chunk := file.read(1024)):.
  • Reach for the while...else clause only when it genuinely improves clarity (typically “search” loops) — it’s a lesser-known feature and can confuse readers if used elsewhere.
  • Avoid deeply nested while loops; extract the inner loop into a helper function if it starts to hurt readability.
  • When looping over a collection while modifying it, iterate carefully — popping items with while my_list: is safe, but modifying indices in a plain index-counter loop can skip or reprocess elements.

Practice Exercises

  • Exercise 1: Write a while loop that prints every even number from 2 to 20 (inclusive).
  • Exercise 2: Given numbers = [4, 9, 15, 22, 7, 3, 40], use a while loop with break to find and print the first number greater than 20. If none exists, use a while...else clause to print "No number over 20 found".
  • Exercise 3: Simulate a countdown from 10 to 1, printing each number, and then print "Liftoff!" after the loop ends. Hint: decrement the counter each iteration and stop the condition when it reaches 0.

Summary

  • A while loop repeats its body as long as its condition remains truthy, re-evaluating the condition fresh before every iteration.
  • You must update a variable used in the condition somewhere in the loop body, or you risk an infinite loop.
  • break exits the loop immediately; continue skips to the next condition check.
  • The optional else clause on a while loop runs only if the loop completes without hitting a break.
  • Use while when the number of iterations isn’t known ahead of time; use for when iterating a known sequence or range.