All 57 lessons

Lesson 10 of 57 · Control Flow

while Loops, break and continue

By Skillancy Editorial Team

Run the code in the free Python Compiler or on your own computer. Lessons that read files use the FreshBasket practice data: download the dataset (ZIP).

A for loop is perfect when you know what you are looping over: these 4 cities, those 6,000 orders, the numbers 1 to 10. But some jobs do not have a known number of repetitions. Keep asking until the user types a valid answer. Keep retrying an API call until it succeeds. Keep adding stock until the shelf is full. Keep compounding growth until revenue doubles. These are jobs for the while loop, which repeats as long as a condition is true.

A while loop is also the loop that can run forever if you are careless, so this lesson spends time on how to design loops that always finish. You will learn the structure, the typical patterns (counters, sentinels, accumulating until a target is reached), the break and continue statements, the little-known else clause on loops, and how to avoid the dreaded infinite loop.

The shape of a while loop

while condition:
    # body: runs again and again while condition is true
    ...

Python checks the condition. If it is true, the body runs and the condition is checked again. This repeats until the condition becomes false, and then execution continues after the loop. If the condition is false the very first time, the body never runs at all.

For a loop to end, something inside the body must eventually make the condition false. A safe while loop therefore has three parts:

1. Initial state: a variable set before the loop.

2. Condition: a test that uses that variable.

3. Progress: a statement in the body that changes the variable towards ending the loop.

Forgetting the third part is the classic cause of an infinite loop. If your program ever seems stuck, press Ctrl+C in a terminal (or the stop button in a notebook) to interrupt it.

Worked examples

Example 1: A countdown

Question: Print a countdown from 5 to 1, then announce the launch.

count = 5

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

print("Delivery launched!")

Output

5
4
3
2
1
Delivery launched!

How it works: The initial state is count = 5. Each pass prints the value and subtracts one, which moves the loop towards the exit. When count reaches 0 the condition count > 0 is false and the loop ends.

Reading the result: The output is 5, 4, 3, 2, 1 followed by the message. The last value printed is 1, not 0, because the condition is tested before each pass. If you forgot count -= 1, the loop would print 5 forever.

Example 2: Keep going until a target is reached

Question: FreshBasket has 150 daily orders in a new city and grows 8% a month. After how many months does it first exceed 300 orders a day?

import math

orders = 150
months = 0

while orders <= 300:
    orders *= 1.08
    months += 1

print(months, round(orders, 1))
print(round(math.log(2) / math.log(1.08), 2))

Output

10 323.8
9.01

How it works: We do not know in advance how many months it will take, which is exactly when while is the right tool. Each pass applies a month of growth and counts the month. The loop stops as soon as the orders exceed 300.

Reading the result: It takes 10 months, at which point daily orders are 323.8. The second printed number is a cross-check with mathematics: doubling at 8% a month takes log(2) / log(1.08), about 9.01 months. Because the loop condition is orders <= 300, exactly reaching 300 would not stop it, so it runs until the first whole month beyond that point.

Example 3: Depleting stock until the reorder point

Question: A store starts the day with 240 litres of milk and sells 37 litres an hour. Reorder when stock falls below 60 litres. At which hour does that happen?

stock = 240
hour = 0
history = [stock]

while stock >= 60:
    stock -= 37
    hour += 1
    history.append(stock)

print(history)
print(f"Reorder needed after hour {hour}, stock is {stock} litres")

Output

[240, 203, 166, 129, 92, 55]
Reorder needed after hour 5, stock is 55 litres

How it works: The loop sells another hour of milk and records the new level. We keep the full history in a list to see the trend. The loop exits on the first hour when the stock drops below the threshold.

Reading the result: The stock went 240, 203, 166, 129, 92, 55, so after hour 5 only 55 litres remain, below the reorder point of 60. Note that the loop never lets stock go below zero here, but with a different threshold it could, so real inventory logic usually adds a check.

Example 4: break to leave early

Question: Scan delivery times in order and stop at the first one that is over 40 minutes.

times = [22, 27, 31, 24, 46, 29, 52]
position = 0

while position < len(times):
    if times[position] > 40:
        print(f"First very late delivery: {times[position]} min at position {position}")
        break
    position += 1
else:
    print("No delivery over 40 minutes")

Output

First very late delivery: 46 min at position 4

How it works: We walk through the list by position. break leaves the loop the moment we find a match. The else attached to the while runs only if the loop ended without hitting break, which makes it a neat "not found" branch. (This while/else form is unusual, and you will see it more often with for.)

Reading the result: The 46-minute delivery was found at position 4, so break ran and the else message was skipped. Remove the 46 and 52 from the list, and the else message would appear instead.

Example 5: continue to skip items

Question: Add up the delivery times, but ignore invalid placeholder values of 999.

readings = [24, 999, 31, 27, 999, 18]
total, valid, i = 0, 0, 0

while i < len(readings):
    value = readings[i]
    i += 1
    if value == 999:
        continue
    total += value
    valid += 1

print(total, valid, round(total / valid, 1))

Output

100 4 25.0

How it works: We increment i before the continue, otherwise a skipped item would never advance the position and the loop would repeat forever. continue jumps back to the condition check, skipping the rest of the body.

Reading the result: After ignoring the two placeholders, the 4 valid readings total 100 minutes, an average of 25.0. A common bug with continue in while loops is skipping the update step, so update first.

Example 6: The while True pattern for validation

Question: Keep asking for a pincode until a valid six-digit one is entered.

while True:
    pincode = input("Enter pincode: ")
    if len(pincode) == 6 and pincode.isdigit():
        break
    print("Invalid, try again.")

Here is a replay of a session where the user types 5600, then abcdef, then 560034:

while True:
    pincode = input("Enter pincode: ")
    if len(pincode) == 6 and pincode.isdigit():
        break
    print("Invalid, try again.")

print("Accepted:", pincode)

Output

Enter pincode: 5600
Invalid, try again.
Enter pincode: abcdef
Invalid, try again.
Enter pincode: 560034
Accepted: 560034

How it works: while True is deliberately an endless loop, and break is the single, explicit exit. This reads naturally for "keep trying until it works" and avoids duplicating the input() line before and inside the loop.

Reading the result: The first two answers were rejected with the "Invalid" message, and the third, 560034, passed both checks and ended the loop. Every while True must have a reachable break (or return), otherwise it is a genuine infinite loop.

Example 7: Retry with a limit

Question: Simulate calling a flaky service that succeeds on the third attempt, but give up after 5 attempts so we never loop forever.

def call_service(attempt):
    """Pretend service: fails twice, then works."""
    return attempt >= 3

attempt = 0
max_attempts = 5
success = False

while attempt < max_attempts and not success:
    attempt += 1
    success = call_service(attempt)
    print(f"Attempt {attempt}: {'OK' if success else 'failed'}")

print("Final:", "success" if success else "gave up")

Output

Attempt 1: failed
Attempt 2: failed
Attempt 3: OK
Final: success

How it works: The condition combines two reasons to stop: the attempt limit and success. A loop with a maximum attempts guard is the standard safety net for network calls, because the service might never recover. In the API lesson you will do this for real with the mock server.

Reading the result: Attempts 1 and 2 failed and attempt 3 succeeded, so the loop ended after 3 tries instead of running all 5. Always cap retries.

Example 8: Processing in batches

Question: 23 orders need to be sent for packing in batches of 10. How many batches, and how big is each?

pending = 23
batch_size = 10
batches = []

while pending > 0:
    this_batch = min(batch_size, pending)
    batches.append(this_batch)
    pending -= this_batch

print(batches)

Output

[10, 10, 3]

How it works: Each pass takes up to ten orders. min(batch_size, pending) makes the last batch smaller when fewer than ten remain. The pending counter shrinks until nothing is left.

Reading the result: The batch sizes are 10, 10 and 3. Paginated APIs and chunked file uploads follow this very shape: fetch a page, process it, repeat until there is nothing left.

Example 9: Spotting an infinite loop safely

Question: What does an infinite loop look like, and how do we protect ourselves while learning?

safety = 0
n = 10

while n > 0:           # BUG: n never changes, so this loop never ends by itself
    safety += 1
    if safety == 5:    # our emergency exit while we investigate
        print("Stopped after 5 passes; n is still", n)
        break

Output

Stopped after 5 passes; n is still 10

How it works: The condition n > 0 stays true because nothing changes n. We added a safety counter and a break after five passes, which is a common technique when debugging a suspected infinite loop: add a temporary counter and print the variables involved.

Reading the result: After 5 passes n was still 10, which proves the loop makes no progress. The fix is to add n -= 1 inside the loop, so that the variable in the condition really changes.

Common mistakes

1. Not changing the loop variable. The condition never becomes false, so the loop never ends.

2. Updating the variable after continue. The skipped statements never run, and the loop can hang. Update first.

3. Off-by-one in the condition. while count > 0 and while count >= 0 differ by a whole pass.

4. Using while when for is simpler. If you are looping over a known collection or a fixed number of times, for is shorter and safer.

5. Forgetting the exit in while True. Always make sure a break or return can be reached.

while count > 0
    count -= 1

Output

  File "example.py", line 1
      while count > 0
                     ^
  SyntaxError: expected ':'

Practice questions

Practice 1 (Easy): Double until a million

Starting from a revenue of ₹1,000 that doubles each month, find how many months it takes to reach at least ₹1,000,000.

Show solution
revenue, months = 1000, 0
while revenue < 1_000_000:
    revenue *= 2
    months += 1
print(months, revenue)

Output

10 1024000

We do not know the number of months in advance, so while is the natural fit. It takes 10 months, ending at ₹1024000.

Practice 2 (Medium): Digit sum

Use a while loop and the % and // operators to add up the digits of 48,271.

Show solution
number = 48271
digit_total = 0

while number > 0:
    digit_total += number % 10
    number //= 10

print(digit_total)

Output

22

number % 10 is the last digit; number //= 10 removes it. After five passes the number reaches 0 and the loop ends. The digits 4+8+2+7+1 sum to 22.

Practice 3 (Hard): Loan-style payoff

A customer owes ₹12,000 on a FreshBasket credit line with 2% monthly interest, and pays ₹1,500 a month at the end of each month (after interest is added). How many months until the debt is cleared, and what is the final, smaller payment?

Show solution
balance = 12000
months = 0

while balance > 0:
    balance *= 1.02
    payment = min(1500, balance)
    balance -= payment
    months += 1

print(months, round(payment, 2))

Output

9 1209.17

Each month interest is added first, then the payment is subtracted. min(1500, balance) ensures the last payment is only what is still owed, so the balance ends at exactly zero instead of going negative. The debt takes 9 months, and the final payment is ₹1209.17.

Key takeaways

  • A while loop repeats as long as its condition is true, checking the condition before every pass.
  • Every safe loop has an initial state, a condition, and a statement that moves toward ending.
  • Use while when the number of repetitions is unknown; use for for known collections.
  • break exits at once, continue skips to the next check (update your counter first), and loop else runs only if no break happened.
  • while True with an explicit break is the idiom for validation and retry loops; always include a maximum number of attempts for network work.
  • If a loop seems stuck, interrupt it, add a safety counter and print the variables in the condition.

Frequently asked questions

When should I use while instead of for?

Use for when you loop over a known collection or a fixed count. Use while when the number of repetitions depends on something that changes during the loop, such as a target, a user's input, or a retry result.

How do I stop a loop that will not end?

In a terminal press Ctrl+C. In Jupyter or Colab use the stop (interrupt) button. In an editor you may need to close the run window. Afterwards add a safety counter while you debug.

What does the else clause on a loop do?

It runs when the loop finishes normally, without a break. It is mostly used for "search not found" logic. Many Python programmers find it surprising, so comment it clearly or use a flag variable instead.

Is while True bad style?

No, it is a standard idiom, as long as there is a clear break or return. It often reads better than repeating the same line before and inside the loop.

Can I nest while loops?

Yes, and mix them with for loops too. Keep nesting shallow, because every level multiplies the work and makes the logic harder to follow.

How do I loop until a file or API runs out of data?

Use a while loop that fetches the next chunk and breaks when the chunk is empty, as in the batches example. The API lesson shows pagination using this pattern.

Newsletter

Keep learning Python

One email a week with Python and analytics guides, new practice questions and cohort dates. No spam, unsubscribe anytime.

Ready to practise? Try the Python interview questions