while Loops, break, continue and else on Loops

While loops execute a block of code repeatedly as long as a condition is True โ€” unlike for loops which iterate over a fixed sequence, while loops are used when the number of iterations is not known in advance. Python adds two loop control tools โ€” break (exit the loop immediately) and continue (skip to the next iteration) โ€” and a unique else clause on loops that runs only when the loop completes normally without hitting a break. In FastAPI you will use while loops for retry logic, polling, and processing streaming data, and the else clause for search patterns where you need to know whether a break was triggered.

Basic while Loop

# Repeat as long as condition is True
count = 0
while count < 5:
    print(count)
    count += 1      # Must update the condition variable!
# 0, 1, 2, 3, 4

# Countdown
n = 5
while n > 0:
    print(n)
    n -= 1
print("Done!")
# 5, 4, 3, 2, 1, Done!

# while True โ€” infinite loop controlled by break
attempts = 0
while True:
    user_input = input("Enter a number: ")
    if user_input.isdigit():
        break                    # exit loop when valid input received
    print("Invalid โ€” try again")
    attempts += 1
    if attempts >= 3:
        print("Too many attempts")
        break
Note: Every while loop must have a mechanism to eventually make its condition False, or a break statement that exits the loop. Forgetting to update the loop variable is the most common cause of infinite loops โ€” the program hangs forever consuming 100% CPU. If your program seems frozen during development, press Ctrl+C to interrupt it and check your while loop logic.
Tip: The while True: ... break pattern (also called a “loop and a half”) is the cleanest way to handle “check condition after at least one iteration” scenarios โ€” like reading user input or polling an endpoint until a condition is met. It is more readable than the do...while pattern that JavaScript uses, which Python does not have. Use this pattern in FastAPI background tasks that poll for a status change.
Warning: continue and break only affect the innermost loop. If you have nested loops and want to break out of the outer loop, you need a different approach โ€” either use a flag variable, refactor into a function and use return, or use Python 3.10’s match statement. There is no break 2 or labelled break in Python like in some other languages.

break โ€” Exit the Loop Early

posts = [
    {"id": 1, "title": "First",  "published": True},
    {"id": 2, "title": "Second", "published": False},
    {"id": 3, "title": "Target", "published": True},
    {"id": 4, "title": "Fourth", "published": True},
]

# Find the first published post with id > 2
found = None
for post in posts:
    if post["id"] > 2 and post["published"]:
        found = post
        break   # stop searching โ€” we found it

print(found)   # {"id": 3, "title": "Target", "published": True}

# break in while โ€” retry with limit
import time

def fetch_with_retry(url: str, max_retries: int = 3):
    attempts = 0
    while attempts < max_retries:
        try:
            response = requests.get(url, timeout=5)
            if response.status_code == 200:
                return response.json()
            break   # non-200 but not an exception โ€” stop retrying
        except requests.Timeout:
            attempts += 1
            time.sleep(1)
    return None   # failed after retries

continue โ€” Skip to Next Iteration

posts = [
    {"id": 1, "title": "Draft",     "published": False},
    {"id": 2, "title": "Published", "published": True},
    {"id": 3, "title": "Another",   "published": True},
]

# Process only published posts
for post in posts:
    if not post["published"]:
        continue      # skip unpublished โ€” go to next iteration
    print(f"Processing: {post['title']}")
# Processing: Published
# Processing: Another

# Skip invalid values
data = [1, None, 3, None, 5]
total = 0
for value in data:
    if value is None:
        continue      # skip None values
    total += value
print(total)   # 9

The Loop else Clause

# The else clause runs if the loop completes WITHOUT a break
# It does NOT run if break was triggered

# Common use: search โ€” did we find what we were looking for?
users = [
    {"id": 1, "email": "alice@example.com"},
    {"id": 2, "email": "bob@example.com"},
]

target_email = "charlie@example.com"

for user in users:
    if user["email"] == target_email:
        print(f"Found: {user}")
        break
else:
    # This runs because no break was triggered
    print("User not found")
# User not found

# Compare: if target_email were "alice@example.com":
# loop finds it, break fires, else block is SKIPPED

# while loop also supports else
attempts = 0
while attempts < 3:
    result = try_operation()
    if result:
        break
    attempts += 1
else:
    print("Operation failed after 3 attempts")   # runs if no break

Nested Loops

# Multiplication table
for i in range(1, 4):
    for j in range(1, 4):
        print(f"{i}ร—{j}={i*j}", end="  ")
    print()   # newline after each row
# 1ร—1=1  1ร—2=2  1ร—3=3
# 2ร—1=2  2ร—2=4  2ร—3=6
# 3ร—1=3  3ร—2=6  3ร—3=9

# break only exits the INNER loop
for i in range(3):
    for j in range(3):
        if j == 1:
            break       # exits inner loop only
        print(f"({i},{j})")
# (0,0)
# (1,0)
# (2,0)

# To break out of both loops โ€” use a flag
found = False
for i in range(10):
    for j in range(10):
        if i * j == 42:
            found = True
            break
    if found:
        break
print(f"Found at i={i}, j={j}")

Common Mistakes

Mistake 1 โ€” Forgetting to update the loop variable (infinite loop)

โŒ Wrong โ€” count never changes, loop runs forever:

count = 0
while count < 5:
    print(count)
    # Forgot: count += 1 โ†’ infinite loop! Press Ctrl+C to stop

โœ… Correct โ€” always update the condition variable:

count = 0
while count < 5:
    print(count)
    count += 1   # โœ“ condition will eventually become False

Mistake 2 โ€” Misunderstanding the else clause

โŒ Wrong โ€” thinking else runs when the condition becomes False:

for i in range(3):
    print(i)
else:
    print("Loop done")   # This runs โ€” but it also runs with break!

โœ… Correct โ€” else only runs when NO break occurred:

for i in range(3):
    if i == 1:
        break
else:
    print("No break")   # NOT printed โ€” break was triggered

Mistake 3 โ€” Assuming break exits all nested loops

โŒ Wrong โ€” expecting break to exit the outer loop:

for i in range(3):
    for j in range(3):
        if j == 1:
            break        # only exits inner loop!
    print(f"i={i}")      # this still runs for all i values

โœ… Correct โ€” use a flag variable to break multiple loops.

Quick Reference

Pattern Code
Basic while while condition:
Infinite loop while True: (needs break)
Exit loop break
Skip iteration continue
Else (no break) for ... : ... else: ...
Retry pattern while attempts < max: ... attempts += 1

🧠 Test Yourself

You search a list of users for one with role == "admin". You use a for loop with break and an else clause. When does the else block execute?