Python - While Loop with Examples

A while loop repeats a block of code as long as a condition remains true. Unlike for loops, which iterate over sequences with a known length, while loops continue until something changes that makes...

Key Insights

  • While loops excel when you don’t know how many iterations you need—use them for condition-based repetition rather than counting through sequences
  • Python’s unique while-else clause executes only when the loop completes without hitting a break, making it perfect for search operations
  • Most infinite loop bugs stem from forgetting to update the loop variable inside the loop body—always verify your exit condition can actually become false

Introduction to While Loops

A while loop repeats a block of code as long as a condition remains true. Unlike for loops, which iterate over sequences with a known length, while loops continue until something changes that makes the condition false.

Use a while loop when:

  • You don’t know how many iterations you’ll need
  • You’re waiting for an external condition (user input, network response, file data)
  • You need to repeat until a specific state is reached

Use a for loop when:

  • You’re iterating over a collection
  • You know the exact number of iterations
  • You’re processing each item in a sequence

The mental model is simple: for loops answer “do this for each item,” while loops answer “keep doing this until.”

Basic Syntax and Structure

Python’s while loop syntax is straightforward:

while condition:
    # code block to execute
    # must eventually make condition False

The loop checks the condition before each iteration. If true, it executes the body. If false, it skips the body entirely and continues with the next statement after the loop.

Here’s a simple countdown:

count = 10

while count > 0:
    print(count)
    count -= 1

print("Liftoff!")

Output:

10
9
8
7
6
5
4
3
2
1
Liftoff!

Notice the critical line count -= 1. Without it, count stays at 10 forever, and the condition count > 0 never becomes false. This is the most common source of infinite loops.

Common Use Cases

While loops shine in scenarios where iteration count is unpredictable.

Input Validation

Keep prompting until the user provides valid input:

def get_positive_integer(prompt):
    while True:
        user_input = input(prompt)
        
        if not user_input.isdigit():
            print("Please enter a valid number.")
            continue
            
        value = int(user_input)
        if value <= 0:
            print("Number must be positive.")
            continue
            
        return value

age = get_positive_integer("Enter your age: ")
print(f"You are {age} years old.")

This pattern—while True with explicit return or break—is cleaner than trying to construct a complex condition upfront.

Number Guessing Game

Games often need loops that run until a win/lose condition:

import random

def guessing_game():
    target = random.randint(1, 100)
    attempts = 0
    max_attempts = 7
    
    print("I'm thinking of a number between 1 and 100.")
    print(f"You have {max_attempts} attempts.")
    
    while attempts < max_attempts:
        guess = input(f"Attempt {attempts + 1}: ")
        
        if not guess.isdigit():
            print("Enter a valid number.")
            continue
        
        guess = int(guess)
        attempts += 1
        
        if guess < target:
            print("Too low!")
        elif guess > target:
            print("Too high!")
        else:
            print(f"Correct! You got it in {attempts} attempts.")
            return True
    
    print(f"Game over. The number was {target}.")
    return False

guessing_game()

The loop has two exit paths: the player guesses correctly (early return) or runs out of attempts (condition becomes false).

Loop Control: break, continue, and else

Python provides three mechanisms for controlling loop flow.

break: Exit Immediately

break terminates the loop entirely, skipping any remaining iterations:

def find_first_negative(numbers):
    index = 0
    
    while index < len(numbers):
        if numbers[index] < 0:
            print(f"Found negative number {numbers[index]} at index {index}")
            break
        index += 1
    else:
        print("No negative numbers found")

find_first_negative([5, 3, 8, -2, 7])  # Found negative number -2 at index 3
find_first_negative([5, 3, 8, 2, 7])   # No negative numbers found

continue: Skip to Next Iteration

continue skips the rest of the current iteration and jumps back to the condition check:

def process_valid_entries(entries):
    index = 0
    processed = []
    
    while index < len(entries):
        entry = entries[index]
        index += 1
        
        if entry is None or entry == "":
            continue  # Skip invalid entries
        
        if isinstance(entry, str) and entry.startswith("#"):
            continue  # Skip comments
        
        processed.append(entry)
    
    return processed

data = ["value1", None, "# comment", "value2", "", "value3"]
result = process_valid_entries(data)
print(result)  # ['value1', 'value2', 'value3']

Note that index += 1 comes before the continue statements. If it came after, skipped entries would cause an infinite loop.

while-else: The “No Break” Clause

Python’s else clause on loops is often misunderstood. It executes only if the loop completes normally—without hitting a break:

def search_inventory(items, target):
    index = 0
    
    while index < len(items):
        item = items[index]
        if item["name"] == target:
            print(f"Found '{target}' with {item['quantity']} in stock")
            break
        index += 1
    else:
        print(f"'{target}' not found in inventory")

inventory = [
    {"name": "keyboard", "quantity": 15},
    {"name": "mouse", "quantity": 42},
    {"name": "monitor", "quantity": 8},
]

search_inventory(inventory, "mouse")     # Found 'mouse' with 42 in stock
search_inventory(inventory, "webcam")    # 'webcam' not found in inventory

Think of else as “if no break.” It’s perfect for search patterns where you need different behavior for “found” versus “not found.”

Infinite Loops and How to Avoid Them

Infinite loops aren’t always bugs. Server processes, event listeners, and monitoring systems intentionally run forever:

import time

def server_loop():
    """Simulated server that processes requests until shutdown."""
    running = True
    request_count = 0
    
    while running:
        # Simulate checking for incoming requests
        request = get_next_request()  # Would block until request arrives
        
        if request == "SHUTDOWN":
            print("Shutdown signal received")
            running = False
            continue
        
        process_request(request)
        request_count += 1
        
        if request_count % 100 == 0:
            print(f"Processed {request_count} requests")
    
    print(f"Server stopped after {request_count} requests")

Accidental infinite loops are a different story. Here’s a common mistake:

# BUG: Infinite loop
numbers = [1, 2, 3, 4, 5]
index = 0
total = 0

while index < len(numbers):
    if numbers[index] % 2 == 0:
        total += numbers[index]
        continue  # Oops! index never increments for even numbers
    index += 1

print(total)

The fix: increment index before continue, or restructure the logic:

# Fixed version
numbers = [1, 2, 3, 4, 5]
index = 0
total = 0

while index < len(numbers):
    if numbers[index] % 2 == 0:
        total += numbers[index]
    index += 1  # Always increment

print(total)  # 6

Debugging tips for infinite loops:

  • Add print statements to track variable values
  • Set a maximum iteration count during development
  • Use your IDE’s debugger to step through iterations
  • Check that every code path eventually changes the loop condition

While Loops vs For Loops

Sometimes the choice is obvious. Other times, both work but one is cleaner.

Reading lines until empty (while loop is natural):

# While loop - natural fit
lines = []
while True:
    line = input("Enter line (empty to stop): ")
    if not line:
        break
    lines.append(line)

Processing a known list (for loop is natural):

# For loop - natural fit
numbers = [1, 2, 3, 4, 5]
squared = [n ** 2 for n in numbers]

Same task, both approaches:

# Summing a list with for loop
numbers = [10, 20, 30, 40, 50]
total = 0
for num in numbers:
    total += num

# Summing a list with while loop
numbers = [10, 20, 30, 40, 50]
total = 0
index = 0
while index < len(numbers):
    total += numbers[index]
    index += 1

The for loop is clearly better here—less code, no manual index management, impossible to mess up the increment.

Rule of thumb: if you’re managing an index variable just to iterate through a sequence, use a for loop instead.

Best Practices and Summary

Write clean while loops by following these guidelines:

Make exit conditions obvious. The reader should immediately understand when the loop stops:

# Clear exit condition
max_retries = 3
attempts = 0

while attempts < max_retries:
    if try_connection():
        break
    attempts += 1

Avoid complex conditions. If your while condition spans multiple lines, refactor:

# Instead of this
while user_input != "quit" and not error_occurred and retry_count < 3:
    ...

# Consider this
def should_continue():
    if user_input == "quit":
        return False
    if error_occurred:
        return False
    if retry_count >= 3:
        return False
    return True

while should_continue():
    ...

Update loop variables close to the condition check. This makes the logic easier to follow and reduces bugs:

while index < len(items):
    item = items[index]
    # process item
    index += 1  # Update at end, clearly visible

Use while True with break for complex exit logic. It’s often cleaner than cramming everything into the condition:

while True:
    data = fetch_data()
    if data is None:
        break
    if not validate(data):
        continue
    process(data)

While loops are fundamental to programming. Master them by understanding when they’re the right tool, how to control their flow, and how to write them clearly. When you need condition-based iteration, reach for a while loop. When you’re processing sequences, stick with for loops.

Liked this? There's more.

Every week: one practical technique, explained simply, with code you can use immediately.