Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Python Module 3 – Control flow: decisions, loops and pattern matching

while loops, break, continue and loop else

Repeat code with Python's while loop, stop it at the right moment, use break and continue on purpose, and learn when the else clause of a loop runs.

  • Beginner
  • 15 minutes
  • Examples run with Python 3.14.8 and Pyodide 314.0.7
  • By MySmartCoPilot

What you will learn

  • Write while loops with correct stopping conditions
  • Use break and continue deliberately
  • Explain when a loop's else clause runs

Before you start

On this page

A while loop runs a block again and again for as long as its condition is true. It is the loop to use when you cannot say in advance how many times the work must happen: until the user types a sensible answer, until a number reaches 1, until a search finds what it is looking for. (To go through the items of a list or a range of numbers, the for loop of the next lesson is simpler.)

How a while loop runs

A while statement looks like an if: the word while, a condition, a colon and an indented block. The difference is what happens at the end of the block. Python goes back to the top and tests the condition again, and it keeps doing so until the test comes out false. The test happens before every pass, so when the condition is false from the start, the body never runs at all.

Flowchart of a while loop: test, body, back to the test; break goes straight to the code after the loop, skipping else.Is thecondition true?Run the bodyRun the else block(if there is one)The code afterthe looptrueend of the body,or continuefalsebreak

How a while loop runs, with continue, break and else

Text description of the diagram

The diagram is a flowchart of a while loop, read from the top.

  1. Python tests the condition. When it is true, the body runs.
  2. When the body ends, or a continue statement runs inside it, Python goes back to step 1 and tests the condition again.
  3. When the test comes out false, the loop's else block runs, if the loop has one, and then the code after the loop.
  4. A break statement in the body leaves the loop at once: Python goes straight to the code after the loop, and the else block does not run.

This program follows the Collatz rule: halve an even number, triple an odd one and add 1, and stop at 1.

Counting the steps to 1 Python · collatz.py
# The Collatz rule: halve an even number; triple an odd number and
# add 1. Repeat until you reach 1.

n = 6
steps = 0
print(n, end="")
while n != 1:
    if n % 2 == 0:
        n = n // 2
    else:
        n = 3 * n + 1
    steps += 1
    print(" ->", n, end="")
print()
print("Steps:", steps)

n = 27
steps = 0
highest = n
while n != 1:
    if n % 2 == 0:
        n = n // 2
    else:
        n = 3 * n + 1
    steps += 1
    if n > highest:
        highest = n
print("27 needs", steps, "steps and climbs as high as", highest)

Output

6 -> 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
Steps: 8
27 needs 111 steps and climbs as high as 9232

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 collatz.py

Each pass changes n, which is what the condition looks at, and counts one step. That is the rule for every while loop: something in the body must move the loop towards its stopping condition. Starting from 27, the same loop needs 111 steps and climbs to 9,232 before it falls back to 1. Whether every starting number reaches 1 has never been proved: the claim is called the Collatz conjecture, and research papers have so far proved only weaker statements about it. So a loop’s stopping condition is a promise you should be able to explain, not just hope for.

When a loop never stops

A loop whose condition never becomes false runs forever. The usual causes are a body that never changes the variable the condition tests, a change in the wrong direction (n += 1 where n -= 1 was meant), and a condition that steps over its target: with n = 1 and while n != 10:, adding 2 on each pass gives 9 and then 11, so n is never equal to 10. A comparison such as n < 10 stops whether n lands on 10 or jumps past it.

If it happens in a terminal, press Ctrl-C: Python raises KeyboardInterrupt, which ends the program with a traceback that shows the line it was running. In the Run bar of this page, Stop ends a run at once, and a run that goes on for too long is stopped for you.

A common mistake: one step too far

Loops that walk through a list by position are easy to get wrong at the end:

Reading one item past the end Python · off_by_one.py
marks = [72, 85, 64]
total = 0
i = 0
while i <= len(marks):
    total += marks[i]
    i += 1
print("Total:", total)

Output (exit status 1)

Printed as an error (standard error)

Traceback (most recent call last):
  File "off_by_one.py", line 5, in <module>
    total += marks[i]
             ~~~~~^^^
IndexError: list index out of range

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 off_by_one.py

The list has three items, at positions 0, 1 and 2, but i <= len(marks) lets the loop run a fourth time with i equal to 3. Use i < len(marks). The for loop of the next lesson does this counting for you, which is why lists are usually walked with for.

break and continue

Two statements change the course of a loop from inside its body:

  • break leaves the loop at once. Python goes on with the first line after the loop.
  • continue skips the rest of this pass. In a while loop, Python goes straight back to testing the condition.

Both act on the innermost loop they are in, and both are normally written inside an if, so that they happen only in some passes.

while True with break

When the loop can only decide whether to stop halfway through its body, write while True: and leave with break. Asking for input until it makes sense is the classic case:

Ask again until the answer is valid Python · ask_age.py
# Keep asking until the answer is a whole number from 1 to 120.
while True:
    text = input("Your age: ").strip()
    if not text.isdecimal():
        print("Please type your age in digits.")
        continue
    age = int(text)
    if not 1 <= age <= 120:
        print("An age from 1 to 120, please.")
        continue
    break

print("Thank you. Your age is", age)

Input (standard input)

twenty
²
0
250
34

Output

Your age: Please type your age in digits.
Your age: Please type your age in digits.
Your age: An age from 1 to 120, please.
Your age: An age from 1 to 120, please.
Your age: Thank you. Your age is 34

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 ask_age.py

The program was given five answers, shown above its output. “twenty”, “²”, “0” and “250” are rejected, each with a message, and continue goes back to input() for the next answer; 34 passes both checks and break ends the loop. The answers do not appear after the prompts because the program read them from standard input, not from a keyboard; answers typed at a keyboard would have shown on the screen as they were typed.

isdecimal() is the right check before int(): it is true only for digits that int() can read, including those of other scripts such as ३४. The similar isdigit() also accepts characters such as ², and int("²") fails with ValueError.

continue in a counting loop

continue skips everything below it in the body, including a counter you update at the bottom. Move the counter up:

Skipping failed readings Python · skip_failed.py
# -1 marks a reading that the sensor failed to take
readings = [21, 22, -1, 23, -1, 24]

total = 0
count = 0
i = 0
while i < len(readings):
    value = readings[i]
    i += 1
    if value == -1:
        continue
    total += value
    count += 1

print("Good readings:", count)
print("Average:", total / count)

Output

Good readings: 4
Average: 22.5

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 skip_failed.py

Here i += 1 comes before the continue. Had it stayed at the bottom of the body, the first -1 would have sent the loop back to the test with i unchanged, to read the same -1 forever.

The else clause of a loop

A while loop may end with an else: block. It runs when the loop stops because its condition is false, and it does not run when the loop is left with break (or with return or an exception). That makes it a natural fit for searches: the break means “found it”, and the else means “searched everything, found nothing”.

A search with while and else

First try · factor_search.py

def describe(n):
    divisor = 2
    while divisor * divisor <= n:
        if n % divisor == 0:
            print(n, "=", divisor, "x", n // divisor)
            break
        divisor += 1
    else:
        print(n, "is prime")


describe(91)
describe(97)
describe(2)
describe(1)

Output

91 = 7 x 13
97 is prime
2 is prime
1 is prime

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 factor_search.py

Fixed · factor_search_fixed.py

def describe(n):
    if n < 2:
        print(n, "is neither prime nor composite")
        return
    divisor = 2
    while divisor * divisor <= n:
        if n % divisor == 0:
            print(n, "=", divisor, "x", n // divisor)
            break
        divisor += 1
    else:
        print(n, "is prime")


describe(91)
describe(97)
describe(2)
describe(1)

Output

91 = 7 x 13
97 is prime
2 is prime
1 is neither prime nor composite

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 factor_search_fixed.py

For 91, the loop finds the divisor 7 and leaves with break, so the else is skipped. For 97, no divisor up to 9 works and the next one, 10, is too big (10 × 10 is more than 97), so the condition becomes false and the else reports a prime. Stopping at divisor * divisor <= n is enough because divisors come in pairs, d and n // d, and the smaller of each pair is never above the square root; a later lesson of this module works that out.

The first try gets 1 wrong. For both 2 and 1, divisor * divisor <= n is false from the start, so the body never runs and the else runs at once. That is right for 2 and wrong for 1, which is not a prime. Remember this edge case: an else runs even when the loop did no passes at all. The fixed version deals with numbers below 2 before the loop, with a guard clause.

Prime Number Checker & Generator Check the answers of the factor search for numbers of your own, with the smallest divisor shown.

Version note

New in Python 3.14: a break or continue that would leave a finally block (part of the try statement, covered with exceptions later in this track) makes Python print SyntaxWarning: 'break' in a 'finally' block or the same for continue (PEP 765). Such code can silently swallow an error, so move the break out of the finally block.

Python Online Compiler Try your own while loops with an input box for input(), and Stop for a loop that never ends.

Key takeaways

  • A while loop tests its condition before every pass; if it is false at the start, the body never runs.
  • Something in the body must move the loop towards its stopping condition; prefer < over != for counters, and press Ctrl-C to stop a runaway loop in a terminal.
  • break leaves the innermost loop; continue goes back to the test. Update counters before any continue.
  • while True: with a break in the middle suits input that must be checked before the loop can decide.
  • A loop’s else block runs only when the loop ends without break, also when the body never ran: ideal for searches.

Exercise

Exercise · Easy · Python

Reverse the digits of a number with arithmetic

Write two functions that work on the digits of a whole number with arithmetic alone, inside a while loop. Do not turn the number into text: no str(), no f-strings and no slicing (a sample test checks your file for them).

  • reverse_digits(n) returns n with its digits in reverse order: reverse_digits(1234) is 4321. Zeros at the end of n disappear, so reverse_digits(1200) is 21; the sign stays, so reverse_digits(-56) is -65; and reverse_digits(0) is 0.
  • is_palindrome_number(n) returns True when n reads the same in both directions, such as 121, 7 and 0, and False otherwise, such as for 10 and 123. Negative numbers are never palindromes, because of the minus sign.

For a positive n, n % 10 is its last digit and n // 10 is n without its last digit.

Starter code · digits.py

def reverse_digits(n):
    """Return n with its digits in reverse order; the sign stays."""
    result = 0
    return result


def is_palindrome_number(n):
    """Return True when n reads the same both ways (never if n < 0)."""
    return False
The sample tests · test_digits.py
import ast
from pathlib import Path

from digits import is_palindrome_number, reverse_digits


def test_reverse():
    """reverses the digits of positive numbers"""
    assert reverse_digits(1234) == 4321
    assert reverse_digits(7) == 7
    assert reverse_digits(90817) == 71809


def test_reverse_zeros():
    """drops the zeros at the end, and 0 stays 0"""
    assert reverse_digits(1200) == 21
    assert reverse_digits(10) == 1
    assert reverse_digits(0) == 0


def test_reverse_negative():
    """keeps the minus sign"""
    assert reverse_digits(-56) == -65
    assert reverse_digits(-1000) == -1


def test_palindromes():
    """recognises numbers that read the same in both directions"""
    assert is_palindrome_number(121) is True
    assert is_palindrome_number(4884) is True
    assert is_palindrome_number(7) is True
    assert is_palindrome_number(0) is True


def test_not_palindromes():
    """rejects other numbers, negative ones included"""
    assert is_palindrome_number(10) is False
    assert is_palindrome_number(123) is False
    assert is_palindrome_number(-121) is False


BANNED = ("str", "repr", "format")


def test_arithmetic_only():
    """uses a while loop and no str(), f-strings or slicing"""
    path = Path(__file__).with_name("digits.py")
    nodes = list(ast.walk(ast.parse(path.read_text(encoding="utf-8"))))
    assert any(isinstance(n, ast.While) for n in nodes), "use a while loop"
    for node in nodes:
        if isinstance(node, ast.Call) and isinstance(node.func, ast.Name):
            assert node.func.id not in BANNED, f"no {node.func.id}()"
        assert not isinstance(node, ast.JoinedStr), "no f-strings"
        assert not isinstance(node, ast.Slice), "no slicing"
A hint

Start with result = 0. While n is more than 0, take its last digit with n % 10, add it to the end of the result with result * 10 + digit, and remove it from n with n // 10. For a negative number, reverse -n (which is positive) and put the minus sign back at the end.

The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Check yourself

5 questions about this lesson. Every answer and why it is right is on the page, behind “Show the answer”. Your score stays in this browser.

  1. Question 1 of 5 What does collatz.py print?

    What does this program print? Choose one answer.

    # The Collatz rule: halve an even number; triple an odd number and
    # add 1. Repeat until you reach 1.
    
    n = 6
    steps = 0
    print(n, end="")
    while n != 1:
        if n % 2 == 0:
            n = n // 2
        else:
            n = 3 * n + 1
        steps += 1
        print(" ->", n, end="")
    print()
    print("Steps:", steps)
    
    n = 27
    steps = 0
    highest = n
    while n != 1:
        if n % 2 == 0:
            n = n // 2
        else:
            n = 3 * n + 1
        steps += 1
        if n > highest:
            highest = n
    print("27 needs", steps, "steps and climbs as high as", highest)
    Show the answer to question 1

    Answer: it prints

    6 -> 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
    Steps: 8
    27 needs 111 steps and climbs as high as 9232

    The loop counts one step for each change of n: 6 becomes 3, 10, 5, 16, 8, 4, 2 and finally 1, eight changes. The starting number is printed before the loop and is not a step. When n reaches 1 the test n != 1 is false, so the loop ends after printing 1.

  2. Question 2 of 5 When does the else block of a while loop run?

    Choose one answer.

    Show the answer to question 2

    Answer: When the condition is false, also if it was false before the first pass, but not after a break

    The else block runs when the loop stops because its condition tested false, which may happen on the very first test: that is why describe(1) in the first try of the factor search printed "1 is prime". A break (or a return or an exception) leaves the loop without running it.

  3. Question 3 of 5 What does this print?

    Read the code, then choose one answer.

    n = 0
    while n < 4:
        n += 1
        if n == 2:
            continue
        print(n)
    Show the answer to question 3

    Answer: 1 3 4

    n goes up before the continue, so the loop always moves on. When n is 2, continue skips the print and goes back to the test. The loop stops after n reaches 4, which is printed because 4 < 4 is only tested afterwards.

  4. Question 4 of 5 Which of these loops never stop? (n starts at 1 in each.)

    Choose every answer that is right.

    Show the answer to question 4

    Answer:

    • while n != 10: n += 2
    • while n > 0: n += 1

    Counting up while n > 0 moves away from the stopping condition. Adding 2 to 1 gives only odd numbers, so n != 10 stays true for ever, while n < 10 stops at 11. Tripling reaches 243, which is not below 100, so the loop with n *= 3 ends too.

  5. Question 5 of 5 A break runs inside a while loop that is itself inside another loop. What does it leave?

    Choose one answer.

    Show the answer to question 5

    Answer: Only the innermost loop, the one it is written in

    break leaves the innermost loop it is in; the outer loop goes on with its next pass. Leaving several loops at once takes a flag or a function that returns, as the lesson on nested loops shows.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.