Skip to content
CCC Python Course

while loops, break/continue, sentinels and EOF

Module
M1.6
Lesson
1 of 1
Reading time
4 min

In this lesson

  • Repeat a block for as long as a condition holds, with while.
  • Read values until a sentinel value appears, ending the loop when it does.
  • Exit a loop early with break, and skip straight to the next pass with continue.
  • Recognize the EOFError a loop can raise reading past the end of input, and read every remaining line safely with import sys.

The last module's for loop always runs a fixed number of times, known before the loop starts. Some problems instead repeat a step until some condition becomes true, with no fixed count decided in advance. This lesson covers repeating a block with while, and reading input that ends with a special value instead of a count.

Repeating while a condition holds

A while loop checks its condition before every pass, the same way if does, and keeps running the block below it for as long as that condition stays True.

examples/double_until_limit.py
value = 1limit = 100while value < limit:    value *= 2print(value)

Output

128
Doubling a value until it reaches a limit

value starts at 1 and doubles on every pass: 2, 4, 8, and onward. Python checks value < limit again before each pass, and stops the loop as soon as value reaches 128, the first power of two that is no longer less than 100. Unlike a for loop, nothing here says in advance how many passes that will take.

A while loop that never makes its condition False runs forever. Every while loop needs something inside its block that moves the condition closer to False, the way value *= 2 does here. A for loop cannot run forever this way, since range() always hands it a fixed, already-known sequence of values to visit. A while loop carries that risk instead, in exchange for not needing to know the count in advance. It is worth a second look whenever you write one. Check, by hand, that the block genuinely moves the condition toward False on every single pass.

Reading values until a sentinel appears

Some problems mark the end of their input with a special value, called a sentinel, instead of telling you a count in advance.

examples/sum_until_sentinel.py
total = 0number = int(input())while number != 0:    total += number    number = int(input())print(total)

Input

4
6
0

Output

10
Adding numbers until a 0 sentinel appears

The program reads one number before the loop starts, then checks whether it is the sentinel 0. As long as it is not, the loop adds it to total and reads the next number, right at the bottom of the block. Reading a number both before the loop and again inside it feels repetitive, but it is what lets the condition see the newest number before deciding whether to keep going.

Choosing a sentinel value only works when the problem's own numbers can never legitimately equal it. A count of players, for example, could safely use 0 as a sentinel, since a real count is always at least 1. That same 0 would be a poor choice for a temperature reading, though, since a real reading might genuinely be zero. Always check what a sentinel rules out before relying on one.

Exiting early with break

break exits a loop the instant Python reaches it, no matter what its condition says. It gives you another way to write a sentinel loop, without reading the same line twice in the code.

examples/skip_and_sum.py
total = 0while True:    n = int(input())    if n == 0:        break    if n < 0:        continue    total += nprint(total)

Input

4
-1
6
0

Output

10
Summing positive numbers until a 0 sentinel, skipping negatives

while True: starts a loop whose own condition never turns False on its own, so only the break inside it can end it. Each pass reads one number first, then decides what to do with it: a 0 reaches break and ends the loop right there, before total += n ever runs.

Skipping a pass with continue

continue jumps straight back to the loop's condition, skipping the rest of the current pass. In skip_and_sum.py, a negative number reaches continue before total += n, so it never gets added, while every other pass reaches that line normally.

A loop that runs past the end of input

A while True: loop with no sentinel at all, and no count to stop it, keeps calling input() even after every line has already been read.

examples/eof_pitfall.py
total = 0while True:    total += int(input())print(total)

Input

3
5

Error: EOFError

Traceback (most recent call last):
  File "eof_pitfall.py", line 3, in <module>
    total += int(input())
EOFError
Reading input() one time too many

The input only has two lines, 3 and 5. The loop reads both, adds them, and loops back for a third line that does not exist, so input() raises EOFError instead of returning anything. Whenever a loop reads input with no sentinel and no count, check that something inside it actually stops the loop before the input runs out.

Reading every remaining line safely

Python's standard library has a module named sys, brought in with import, that includes sys.stdin: every line still left to read, handed over one at a time. Unlike input(), each line from sys.stdin still has its newline attached, so a line read this way often needs .strip() before you convert or compare it.

examples/read_to_end.py
import sys
total = 0for line in sys.stdin:    total += int(line)print(total)

Input

3
5
7

Output

15
Summing every remaining line with import sys

for line in sys.stdin: visits each remaining line in turn, stopping cleanly when there are none left, with no EOFError and no sentinel to watch for. This lesson only needs this one idiom for reading to the end of input; the module on imports tours what else import can bring into a program.

Tracing break and continue in one loop

Input
1total = 0
2while True:
3 n = int(input())
4 if n == 0:
5 break
6 if n < 0:
7 continue
8 total += n
9print(total)
Output so far
(nothing printed yet)
Frames and objects, step 1 of 14FramesGlobal frame
Speed
Python starts at the top of the file. Line 1 runs first.
  • Just changed

Figure 1Summing positive numbers, skipping a negative, until a sentinel

Read the steps as text

The program reads numbers in a loop, adding each positive one to a total, skipping negative ones, and stopping when it reads a 0.

No negatives

  1. Python starts at the top of the file. Line 1 runs first.
  2. Line 1 runs: total is created with the value 0. Line 2, while True:, needs no check, so the loop body starts at line 3.
  3. Line 3 runs: n is created with the value 4.
  4. Line 4 checks the condition: it is false, so line 6 runs next.
  5. Line 6 checks the condition: it is false, so line 8 runs next.
  6. Line 8 runs: total changes from 0 to 4. The loop goes back to the top for its next pass, so line 3 runs next.
  7. Line 3 runs: n changes from 4 to 6.
  8. Line 4 checks the condition: it is false, so line 6 runs next.
  9. Line 6 checks the condition: it is false, so line 8 runs next.
  10. Line 8 runs: total changes from 4 to 10. The loop goes back to the top for its next pass, so line 3 runs next.
  11. Line 3 runs: n changes from 6 to 0.
  12. Line 4 checks the condition: it is true, so line 5 runs next.
  13. Line 5 runs; line 9 is next. Reading 0 reaches this break, which exits the loop immediately, skipping every line below it.
  14. Line 9 runs: it prints 10. The program has finished: no lines are left to run.

With a negative to skip

  1. Python starts at the top of the file. Line 1 runs first.
  2. Line 1 runs: total is created with the value 0. Line 2, while True:, needs no check, so the loop body starts at line 3.
  3. Line 3 runs: n is created with the value 4.
  4. Line 4 checks the condition: it is false, so line 6 runs next.
  5. Line 6 checks the condition: it is false, so line 8 runs next.
  6. Line 8 runs: total changes from 0 to 4. The loop goes back to the top for its next pass, so line 3 runs next.
  7. Line 3 runs: n changes from 4 to -1.
  8. Line 4 checks the condition: it is false, so line 6 runs next.
  9. Line 6 checks the condition: it is true, so line 7 runs next.
  10. Line 7 runs. The loop goes back to the top for its next pass, so line 3 runs next. That is what continue does: it skips total += n entirely for this pass.
  11. Line 3 runs: n changes from -1 to 6.
  12. Line 4 checks the condition: it is false, so line 6 runs next.
  13. Line 6 checks the condition: it is false, so line 8 runs next.
  14. Line 8 runs: total changes from 4 to 10. The loop goes back to the top for its next pass, so line 3 runs next.
  15. Line 3 runs: n changes from 6 to 0.
  16. Line 4 checks the condition: it is true, so line 5 runs next.
  17. Line 5 runs; line 9 is next. Reading 0 reaches this break, which exits the loop immediately, skipping every line below it.
  18. Line 9 runs: it prints 10. The program has finished: no lines are left to run.

Both presets read numbers one at a time until a 0 ends the loop. The preset with a -1 in it still reaches the same total as the one without, since continue skips that single pass without changing total at all.

Recap

This lesson covered repeating a block with while for as long as a condition holds, and reading input that ends with a sentinel value instead of a count. It also covered exiting a loop early with break, and skipping a single pass with continue. Last, it covered the EOFError an unstoppable input loop eventually raises, and reading every remaining line safely with import sys. The three problems below all process values one at a time until something tells the loop to stop.

Practice

Try these on the judges. Each link opens the problem on WMOJ or DMOJ.

  1. 2024 J2
    Dusa And The Yobis (opens on WMOJ in a new tab) WMOJ

    Grow a creature by feeding it smaller creatures, one at a time, until it meets one it cannot eat.

  2. 2021 J3
    Secret Instructions (opens on WMOJ in a new tab) WMOJ

    Follow a sequence of instruction codes until a stop code appears.

  3. 2020 J2
    Epidemiology (opens on DMOJ in a new tab) DMOJ

    Simulate an outbreak day by day until the total infected passes a limit.

    Why DMOJ: Tries the same kind of problem on DMOJ, which holds 2014 to 2020.