Embercode
✕
LoopsLesson 2 of 16

45 min read

The while loop in Python

Why this matters

The for loop works well when you can name the number of repeats before the loop starts. Many real problems do not work that way. You keep reading numbers until the user types a stop value. You keep dividing a number by ten until it reaches zero. You keep halving a range until you find a value or run out of room. In each case, the question is "should I go round again?", and the answer depends on what happened in the last round.

The while loop is made for that question. It checks a condition before each iteration and keeps going while the condition is True. You will use it often for searching, for reading input, and for algorithms that stop when a result is good enough. Binary search, which you will write at the end of this lesson, is a standard algorithm, and it is a while loop.

The idea from first principles

Every loop has a test, a body and a jump back. The for loop puts the range in its header, so you can see the whole plan at a glance. The while loop has only the test in its header. Everything else lives in the body, and you are responsible for making the test eventually false.

Here is the shape of a while loop:

while condition:
    body

The condition is an expression that gives True or False. The body is the indented lines under the loop line. The processor does the following each time it reaches the loop:

  1. Evaluate the condition. It gives True or False.
  2. If False, jump past the body and carry on.
  3. If True, run the body once, then go back to step 1.

Step 1 happens before the body runs the first time. So a while loop can run zero times. If the condition is false when the loop starts, the body is skipped completely.

Think of the loop as a flowchart. The test sits at the top. When the test is true, the body runs, and an arrow goes back up to the test. When the test is false, an arrow leaves the loop. The arrow from the body back to the test is the jump that makes the loop repeat.

An everyday analogy: filling a kettle

Think of filling a kettle from a tap. You keep the tap running while the water level is below the line. Each pass, you check the level. When the level reaches the line, you turn the tap off. You do not know in advance how many seconds it will take, because it depends on the flow and the starting level. The rule is simple: keep going while the water is below the line.

The same shape appears in the code. The condition is "the water is below the line". The body is "run the tap for a moment". The thing that changes the answer is the water level, which the body must change. If the tap never adds water, you stand there forever. In code, that is an infinite loop, and the fix is to make sure the body changes what the condition looks at.

The precise version: a counter with a while loop

Here is a simple counter written as a while loop, next to the same counter written as a for loop. Both print the numbers 1 to 3.

Python · editable
Python · editable

Both print the same three lines. The difference is where the parts live. In the while version, the start is the line i = 1 above the loop, and the step is i += 1 at the bottom of the body. Nothing forces you to write the step, which is why forgetting it is the most common while mistake. Python will not complain about the missing step. The program will just run forever.

Python has no ++ operator, so the step is written i += 1. The += form adds the right-hand value to the variable. Writing i++ gives a syntax error, which is shown in the mistakes section.

You will use for when the count is fixed and while when the stopping point depends on what happens during the loop. Do not force one into the other. A good rule is to ask: can I write down the number of repeats before the loop runs? If yes, for is clearer. If no, use while.

Worked example 1: counting digits

A number's digits are the single characters in its decimal form. The number 1234 has four digits. You can count them without turning the number into text. Each division by ten removes the last digit. You keep dividing until nothing is left. You do not know how many digits the number has until the loop finishes, so a while loop fits.

Two operators do the work. % gives the remainder after division, so 1234 % 10 is 4, the last digit. // is floor division. It divides and drops the decimal part, so 1234 // 10 is 123. For positive numbers, // gives the same result as integer division in Java.

Input: 1234

n = int(input())
digits = 0
total = 0
rest = n
while rest > 0:
    total += rest % 10
    rest //= 10
    digits += 1
print(f"Digits: {digits}")
print(f"Digit sum: {total}")

The output is:

Digits: 4
Digit sum: 10

Trace the loop by hand. The variable rest holds the number that is still being split. Here is the trace, written as the state after each pass:

Passrest at the startlast digit rest % 10total after the bodydigits after the bodyrest after the body
11234441123
212337212
3122931
4111040

When rest is 0, the condition rest > 0 is false, and the loop stops. The variable digits is 4 and total is 10.

Notice that the body changes rest on every pass. That is what makes the loop end. If the body did not change rest, the condition would never change, and the loop would run forever. Also notice that digits and total are set before the loop and updated inside it. Variables that carry results from one pass to the next are the normal pattern, and you should always know where each one starts.

Python can also count digits with len(str(n)), which turns the number into text and counts the characters. The loop shows the number-only method, and it does not need the conversion.

Worked example 2: reading until a stop value

Real input often has no known length. One common format says: keep reading numbers until the value -1 appears, and do not add the -1 to the total. The sentinel is a special value that marks the end. Using a sentinel is simpler than counting in advance, but you must make sure the sentinel cannot be a real data value.

Input, one number per line:

5
8
12
-1
value = int(input())
total = 0
count = 0
while value != -1:
    total += value
    count += 1
    value = int(input())
print(f"Count: {count}")
print(f"Total: {total}")

The output is:

Count: 3
Total: 25

The loop reads the first value before the loop starts. That is the trick for a while loop that reads input. You need the value to test the condition, so you read it first, then read again at the bottom of the body. This is called a priming read. If you forget the first read, the condition checks a name that is not set, and the program fails. The first run of the body handles the first real value, and the last read in the body gets the sentinel that stops the loop.

Two things can go wrong. If the input does not contain -1, input() fails when the input ends. You will see the error in the mistakes section. And if a real value could be -1, the loop would stop too early. Pick a sentinel that the data can never contain, or use a different pattern. Sentinels are common in old programs and in test data, but they are not the usual choice for user input.

Worked example 3: reversing digits and testing a palindrome

A palindrome reads the same forwards and backwards, such as 12321. To test one, reverse the digits and compare. Reversing a number is a classic while loop. Each pass takes the last digit off the input and adds it to the end of the result. Adding to the end means shifting the existing digits left first, which is done by multiplying by ten.

The name reversed_number is used on purpose. reversed is a built-in function in Python, and using it as a name would hide it.

Input: 12321

n = int(input())
original = n
reversed_number = 0
while n > 0:
    digit = n % 10
    reversed_number = reversed_number * 10 + digit
    n //= 10
print(f"Reversed: {reversed_number}")
if reversed_number == original:
    print("Palindrome")
else:
    print("Not a palindrome")

The output is:

Reversed: 12321
Palindrome

Trace the reversed value in a small case. Input 120:

Python · editable

The output is:

Reversed: 21
Not a palindrome

The digits come off as 0, 2, 1. The result goes 0, then 0 times 10 plus 2 gives 2, then 2 times 10 plus 1 gives 21. The output is 21, not 021, because a number has no leading zeros. The trailing zero of 120 disappears from the reversed value, so the number test says 120 is not a palindrome. That is the right answer, because the digit strings differ.

A simpler test for text reads the digits as text. Python lets you reverse text with a slice, which is written [::-1] and means "every character, from the end to the start":

Python · editable

With input 120, the output is False. A slice gives a new value and leaves the original alone.

Worked example 4: the Collatz steps

A famous puzzle takes a positive number. If it is even, halve it. If it is odd, multiply by three and add one. Repeat until you reach 1. Nobody has proved that every number reaches 1, but for the numbers people have tried, it does. The number of steps is not known until the loop ends, which makes it a while problem.

Input: 27

n = int(input())
steps = 0
while n != 1:
    if n % 2 == 0:
        n //= 2
    else:
        n = 3 * n + 1
    steps += 1
print(f"Steps: {steps}")

The output is:

Steps: 111

The number 27 takes 111 steps. You do not need to know the path to write the code. You only need the rule: keep going while n is not 1. The if inside the body is the rule for each step, and steps += 1 counts how many times the body ran.

Python integers grow to fit any value, so the odd branch can make n much larger than the start without any risk of wrapping around to a wrong number.

Worked example 5: Euclid's greatest common divisor

Euclid's method is a classic way to find the greatest common divisor, or GCD, of two numbers. The GCD is the largest number that divides both exactly. Euclid's idea is to replace the pair (a, b) with (b, a % b). The loop stops when the second number is 0. The first number is then the answer.

Python lets you change two names in one line. In a, b = b, a % b, the right side is worked out first, using the old values, and then both names are set. That is why the pair can be replaced in one step.

Input: 48 18, on one line

a, b = map(int, input().split())
while b != 0:
    a, b = b, a % b
print(f"GCD: {a}")

The output is:

GCD: 6

The function input() reads the line as text. The method split() cuts the text at the spaces, giving the two pieces "48" and "18". The function map(int, ...) applies int to each piece, so a becomes 48 and b becomes 18.

The trace is short. Here is what the loop sees on each pass:

Python · editable

The output is:

48 18
18 12
12 6
6 0
6

The loop stops when b is 0, and a holds 6. The number of passes is small even for large numbers, because the remainder shrinks fast. Python also has the function math.gcd, which gives the same answer:

Python · editable

The output is 6.

The binary search: a while loop that halves the work

Binary search finds a value in a sorted list by cutting the search range in half each time. You look at the middle value. If it is the target, you are done. If the target is smaller, the answer must be in the left half, so you throw away the right half. If it is larger, you throw away the left half. You keep going until the range is empty.

An analogy helps. Suppose a friend thinks of a number from 1 to 100 and you have to guess it. Guessing 1, then 2, then 3 takes too long. Guessing 50 first tells you the answer is in one half. Each guess removes half the remaining numbers. You need about seven guesses for 100 numbers, because each guess halves the range, and seven halvings take 100 down to below one.

The search needs three variables: lo for the left end of the range, hi for the right end, and mid for the middle index. The loop runs while the range is not empty. A range is empty when lo is greater than hi.

Here is the search for the value 9 in the list [1, 3, 5, 7, 9, 11, 13], one row for each pass:

Passlohimidvalue at midwhat happens next
106377 is less than 9, so lo becomes 4
24651111 is greater than 9, so hi becomes 4
34449found, so found becomes 4 and the loop ends

Watch three things in the table. First, the range always has the target inside it, if the target exists. Second, each step moves either lo or hi to just past mid, which removes the middle value and everything on that side. Third, the loop stops either when mid finds the target or when lo passes hi.

Now type the program. The input is the count, then the sorted values, then the target. Each line is one of those three things.

Input:

7
1 3 5 7 9 11 13
9
n = int(input())
a = list(map(int, input().split()))
target = int(input())
lo = 0
hi = n - 1
found = -1
while lo <= hi and found == -1:
    mid = lo + (hi - lo) // 2
    if a[mid] == target:
        found = mid
    elif a[mid] < target:
        lo = mid + 1
    else:
        hi = mid - 1
print(found)

The output is:

4

The program prints the index of the target. Indexes start at 0, so the value 9 is at index 4. The loop condition has two parts joined by and. The first part, lo <= hi, stops the search when the range is empty. The second part, found == -1, stops it when the value was found. Using both parts keeps the loop from running one step too many after a success.

The a[mid] form reads the value at position mid in the list. Lists are covered in a later module. For now, read a[mid] as "the value at position mid".

Two details matter in the middle calculation. The expression (lo + hi) // 2 is the simplest version. In Java it can overflow, because the sum of two large numbers may be too big for an int. Python integers do not overflow, so the simple form is safe here. The form lo + (hi - lo) // 2 is still the habit to build, because it is safe in languages with fixed-size numbers, and interviewers often check that you know it.

Python also has a standard module called bisect, which does this search for you:

Python · editable

The output is:

4
4

Write the loop yourself when you are learning, and use bisect in real code.

What happens inside a while loop

A while loop is a test at the top, a body, and a jump back to the test. Python checks the condition with the values the names hold at that moment. If the condition is true, the body runs. If the body changes a name, the next check sees the new value.

Each pass re-reads the names in the condition. That means every name the condition depends on must be changed inside the body, or the loop will keep testing the same values. In the digit loop, the condition reads rest, and the body changes rest. In the binary search, the condition reads lo, hi and found, and the body changes lo or hi on every pass except the last, and changes found on the pass that succeeds.

When you read a while loop, look at the condition, then look for the line that changes each name in it. If you cannot find that line, you have found a likely infinite loop.

Why the binary search moves past mid

In the binary search program, the two assignments inside the loop are lo = mid + 1 and hi = mid - 1. Both move past mid, and this is not a style choice. It is the rule that makes the loop finish. To see why, try the wrong version, lo = mid in place of lo = mid + 1, on a small range.

Suppose lo is 4, hi is 5, and the target is larger than the value at index 4. The middle is 4 + (5 - 4) // 2, which is 4 + 0, so mid is 4. The wrong code sets lo to mid, which is 4 again. Nothing changed. The condition lo <= hi is still true, and the next pass computes mid as 4 again. The loop repeats the same comparison forever.

The correct code sets lo to 5. Now the range is 5 to 5, the middle is 5, and the search checks the last candidate. Each pass must make the range smaller, or the loop cannot end. Moving past mid guarantees that, because mid itself has now been checked and removed from the range.

This is an important habit for every search loop. Ask: does each pass shrink the thing the condition measures? If the answer is no for any input, the loop can run forever on that input.

Loop invariants: a fact that stays true

A loop invariant is a fact about the variables that is true before the loop, stays true after every pass, and is true when the loop ends. Invariants are a good way to show that a loop does what it should. They also show that you can reason about code, not only run it.

For binary search, the invariant is: if the target is in the list at all, it is somewhere between lo and hi, inclusive. Check it at each stage. Before the first pass, lo is 0 and hi is the last index, so every position is in range. When the program checks mid and finds the value is smaller than the target, the target cannot be at mid or to its left, because the list is sorted. Setting lo to mid + 1 keeps the invariant. When the loop ends with lo greater than hi, the invariant says the target cannot be in the list, so the answer is -1.

You can use the same reasoning for any loop. Write one sentence about what must stay true, then check that each line of the body keeps it true. If you find a line that breaks the fact, you have found the bug. Invariants are also a good way to explain your code to someone else, because they say why the loop is right, not only what it does.

Choosing a sentinel

A sentinel is a value that marks the end of the data. The rule for choosing one is simple: the sentinel must be a value that the real data can never contain. If the data is ages, -1 is a good sentinel, because no age is negative. If the data is temperatures in a room, -1 might be a real reading, so a different marker, such as the word done, is safer. Reading a word is simple in Python: input() already gives you text, so you compare it with ==.

Two bad choices cause real bugs. The first is a sentinel that the data can contain, such as 0 for a list of scores that includes zero. The loop stops early, and the later values are silently ignored. The second is a sentinel that changes the total. If the stop value is added before the check, it corrupts the sum. In the program with -1, the check happens before the addition, so the stop value is never added. Always check the sentinel before you use the value.

Sentinels are common in old files and test data, because they are easy to produce. Many modern programs avoid them and use the end of the input instead. Use a sentinel only when the problem says so, or when the input format requires it.

Reading until the input ends

There are two common ways to read input of unknown length. Each one fits a different problem, and an interviewer may ask you to explain the trade-off.

The first is the priming read with a sentinel, as in the program that stops at -1. You read one value before the loop, test it in the condition, and read the next value at the bottom of the body. It works when the input has a stop marker and the marker cannot be a real value. If the marker is missing, the program fails with an EOFError, which is shown in the mistakes section.

The second is reading until the input simply ends, with no marker. Python has no hasNextInt method for this. The usual approach is to read all the input as text, split it into words, and loop over the words with a for loop:

Python · editable

With input 5 8 12, the output is Total: 25. With empty input, the output is Total: 0, because the loop body never runs. The sys module gives access to the standard input, which is the stream of text the program receives. The method read() reads all of it at once, and split() cuts it into words at any whitespace.

When the problem says "read until the end of the input", read the whole input and loop over the words. When the problem says "read until the user types a stop value", use the sentinel form and say what the stop value is.

A checklist for every while loop

Use this checklist when you write a while loop, and when you review one written by someone else. Each question should have a clear answer.

  • Before the loop: is every name in the condition set to a value that makes sense? Is the first test about the right starting state?
  • In the body: which line changes each name that the condition reads? If you cannot point to a line, the loop may never end.
  • Does each pass make progress toward the stop? For a counter, does it move toward the limit? For a range, does it get smaller? For input, does the read move forward?
  • After the loop: what does each name hold now? Is that the answer you need? Is it correct when the loop never ran?
  • For the edge cases: what happens with zero, with one item, with a very large value, and with input that is missing or invalid?

A while loop is short on the page, so a missing piece is easy to overlook. Running through the checklist takes a minute and catches most of the errors that cause infinite loops and wrong answers.

Common mistakes

These are the mistakes that appear most often with while loops. Each one has an error message or an observable symptom.

Forgetting the update

The loop below never ends, and Python does not report anything wrong with it:

i = 1
while i <= 3:
    print(i)

The program prints 1 forever. The body does not change i, so the condition is always true. If you see the same line repeated, look at what the condition tests and find the line that should change it. In this case, add i += 1 at the bottom of the body.

The output below was taken with a time limit of one second. The first four lines are:

1
1
1
1

Each line is the same number, with no end.

Using = instead of ==

In a condition, == tests equality and = assigns a value. Python will not let you use an assignment where a condition belongs:

Python · editable

The output ends with:

  File "main.py", line 2
    while n = 0:
          ^^^^^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?

The message points to the = inside the condition. The fix is while n != 0: or while n == 0:, depending on what you want.

Using ++ instead of += 1

Python has no ++ operator. This line causes a syntax error:

Python · editable

The output ends with:

  File "main.py", line 4
    i++
       ^
SyntaxError: invalid syntax

The fix is i += 1.

A missing colon or indent

A while line must end with a colon. Without it, Python reports this:

Python · editable

The output ends with:

  File "main.py", line 2
    while n != 0
                ^
SyntaxError: expected ':'

The body must be indented too. The error text for a missing indent is the same as for a for loop, which is shown in the previous lesson.

Reading past the end of the input

The program from worked example 2 reads until -1. If you type 5, 8, 12 and stop there, without the -1, the loop calls input() a fourth time, and there is no line left. The program fails:

Python · editable

With input 5, 8, 12, the output ends with:

Traceback (most recent call last):
  File "main.py", line 7, in <module>
    value = int(input())
                ~~~~~^^
EOFError: EOF when reading a line

EOFError means the program tried to read past the end of the input. The fix is either to include the stop value in the input, or to read the input in the way shown in the section on reading until the input ends.

Text where a number is needed

input() always gives text. Adding it to a number fails:

Python · editable

With input 5 and 6, the output ends with:

Traceback (most recent call last):
  File "main.py", line 4, in <module>
    total += input()
TypeError: unsupported operand type(s) for +=: 'int' and 'str'

The fix is total += int(input()).

A stale variable in the condition

If the condition uses a name that the body does not change, the loop runs the same test every time. This often happens when you change a copy and not the original. In the digit-reversal example, original keeps the starting value on purpose, so the comparison at the end uses the right number. If you had written n in the final comparison, it would be zero by then, and every number would look like a palindrome of zero. Always be clear which name is the working copy and which is the saved value.

Debugging walkthrough: a loop that runs one time too many

Here is a counter that should count how many numbers are between 1 and n. It is given n equal to 5 and prints 11.

Python · editable

The output is:

11

Step 1: decide what the expected value is. The first loop counts 5 numbers, which is correct. The second loop is the bug. It starts again from zero and runs while i is at most 5, so it counts 6 more, and the total is 11 instead of 5.

Step 2: put a print statement inside each loop, so you can see when each pass runs. Print i and count on every pass. The output tells you that the second loop starts at zero and runs six times.

Step 3: fix the cause. The second loop is not needed. Delete it, and the output becomes 5.

Step 4: test with another value, such as n equal to 0. The first loop does not run, so the output must be 0. That checks the empty case as well as the normal case.

The method is the same one you used for the for loop. Predict the value, observe the real value, and find the first place where they differ. Print statements are fine while you learn. Later you will use a debugger, which pauses at each line and lets you read every variable.

Edge cases to check every time

Edge cases often break loops that work for typical input. For each while loop, check these cases.

Zero iterations: if the condition is false from the start, the body never runs. With the digit loop, the digit count of 0 is 0, which is the loop's answer, and the digit sum of 0 is also 0. The number 0 itself has one digit, though. The loop cannot see that, because it never runs for 0. A small fix is to check for 0 before the loop.

Negative input: the digit loop uses n > 0, so a negative number is skipped. If negatives are allowed, take the absolute value first with abs(n), or handle the sign separately.

A very large input: Python integers have no fixed limit, so a number with 31 digits works without any change. The digit loop prints the count and the sum for 10 ** 30:

Python · editable

With input 1 followed by thirty 0s, the output is:

Digits: 31
Digit sum: 1

A target that does not exist: the binary search prints -1 when the range becomes empty. Always test a value smaller than the first element and larger than the last.

Duplicates: the binary search returns some index of a value that appears more than once, not necessarily the first. If the problem asks for the first index, the search needs a small change, and you will see that as an exercise.

Interview-style patterns

A while loop shows up in interviews in a few standard shapes. Learn to recognise them.

The first is the search loop, where you narrow a range until you find or lose the answer. Binary search is the best-known form, and its time is O(log n) because the range halves each pass. You need to know how many passes it can take. For n equal to 1000000, about 20 passes are enough, since 2 to the power of 20 is 1048576, which is more than a million.

The second is the process loop, where you apply a rule until a stop condition holds, such as the digit loop or Euclid's method. The time depends on how fast the value shrinks. The digit loop takes about as many passes as the number has digits, which is O(log n) in the value.

The third is the read loop, where input decides the end. Interviewers often ask how you would read input of unknown length. The answer is a priming read with a sentinel, or reading all the input and looping over its words, which is the cleaner choice when the input simply ends.

When the interviewer asks for complexity, name the variable that controls the passes. For binary search, that is the range size, which halves each pass. For the digit loop, it is the number of digits. Naming the variable shows you understand why the time has the shape it has.

Real-world uses

A while loop reads a network stream until the connection closes. A spell checker keeps asking for the next word until the file ends. A game loop keeps drawing frames while the player has not quit. A search function, such as the one a phone uses to find a contact, narrows the list until it finds a match or runs out. A payment system keeps retrying a request while the response is a temporary error and the number of tries is below a limit.

In each case, the loop's body must change the thing the condition checks. A game loop that never checks whether the player quit will never stop. A retry loop that never increments its counter will retry forever, which is a serious bug in production systems. Build the update into your habit from the first time you write a while loop.

Practice

Try each exercise before you open the solution. Use a trace table where it helps.

  1. Print the numbers from 1 to 10 with a while loop instead of a for loop.
  2. Read one integer and print how many times you can divide it by 2 before it becomes 0.
  3. Read integers until the value 0 appears, then print how many numbers were read before the 0. Do not count the 0.
  4. Read an integer and print the sum of its digits.
  5. Print the powers of 2 that are less than or equal to 1000: 1, 2, 4, and so on.
  6. Read a positive integer n and print the smallest power of 10 that is greater than n. For n equal to 999, print 1000.
  7. Change the binary search so it prints the first index of the target when the list has duplicates. Test with the input 5, then 1 2 2 2 3, then 2. The answer is 1.
  8. Write a loop that reads integers and stops when the total of the numbers read so far is at least 100. Print the count of numbers read. Test with input 30, 50, 20.
  9. Explain in words why while x = 5: is a syntax error, then write the correct condition for "x is not equal to 5".
  10. Given rest = 0, predict what the digit count loop prints, and explain why the answer is 0 and not 1.

Show the answer

Exercises 2, 3, 4, 6 and 8 read input. The others print directly.

# 1
i = 1
while i <= 10:
    print(i)
    i += 1
 
# 2: input 10 gives 4, because 10, 5, 2, 1 are the values before 0.
n = int(input())
halvings = 0
while n > 0:
    n //= 2
    halvings += 1
print(halvings)
 
# 3: input 4, 7, 9, 0 gives 3.
count = 0
value = int(input())
while value != 0:
    count += 1
    value = int(input())
print(count)
 
# 4: input 1234 gives 10.
n = int(input())
total = 0
while n > 0:
    total += n % 10
    n //= 10
print(total)
 
# 5
p = 1
while p <= 1000:
    print(p)
    p *= 2
 
# 6: input 999 gives 1000.
n = int(input())
p = 1
while p <= n:
    p *= 10
print(p)
 
# 7: keep searching to the left when a match is found.
# Input: 5, then 1 2 2 2 3, then 2. The answer is 1.
n = int(input())
a = list(map(int, input().split()))
target = int(input())
lo = 0
hi = n - 1
found = -1
while lo <= hi:
    mid = lo + (hi - lo) // 2
    if a[mid] == target:
        found = mid
        hi = mid - 1
    elif a[mid] < target:
        lo = mid + 1
    else:
        hi = mid - 1
print(found)
 
# 8: input 30, 50, 20 gives 3, because the total reaches 100 on the third number.
total = 0
count = 0
while total < 100:
    total += int(input())
    count += 1
print(count)
 
# 9: an assignment is not a test, so Python reports a syntax error.
# The condition for "not equal to 5" is: while x != 5:
 
# 10: the body never runs for 0, so the digit count is 0.
# The loop does not see that 0 has one digit. A check before the loop fixes this.
rest = 0
digits = 0
while rest > 0:
    rest //= 10
    digits += 1
print(digits)

What you now know

  • A while loop checks its condition before each pass, so it can run zero times.
  • Use while when the number of repeats depends on what happens inside the loop, such as reading until a stop value or narrowing a range.
  • Every name in the condition must change in the body, or the loop never ends.
  • Read the first value before the loop when the condition needs input, then read again inside the body.
  • Read all the input and loop over its words when the input simply ends.
  • Binary search halves the range each pass, so it takes about log base 2 of n passes.

The next lesson covers the do-while loop, which runs its body once before it checks the condition. Python has no do-while statement, so that lesson shows the same idea written with while True and a break.

Practice this topic: coding problems for Loops →

Stuck? Ask the tutor

Ask about anything in this lesson. Answers are short and use simple words.

Sign in to ask the tutor.

← The for loop in Python