Controlling Repetition with While Loops

Introduction: When You Don't Know the Iteration Count

Welcome to the first unit of Controlling Python Loops with While, Break, and Continue! In the previous course, every loop we wrote knew exactly how many passes it would make before it even started: the length of a list, the characters in a string, or the size of a range(). That knowledge was built into the loop itself.

But plenty of real repetition does not work that way. Consider draining a bank balance with monthly payments, doubling a number until it passes a limit, or asking for input until it is finally valid. In each case, we cannot state the number of passes up front; we only know the rule that tells us when to stop.

That is exactly what the while loop gives us: repetition driven by a condition rather than by a collection. In this lesson, we will cover its syntax, the initialize-test-update pattern common to counter- and state-driven while loops, how to trace execution by hand, how to avoid loops that never end, and how to choose between while and for.

The While Loop Syntax and Its Three Essential Parts

A while loop is written with the keyword while, a Boolean condition, a colon, and an indented body:

while <condition>:
    # body: runs again and again while the condition stays true

The condition is evaluated before each pass. If it is true, the body runs, and Python jumps back up to check again; if it is false, the loop ends immediately. An important consequence is that when the condition is false on the very first check, the body never runs at all, not even once.

Because the condition never changes on its own, the loops in this unit rely on a pattern we write ourselves. For counter- and state-driven while loops like the examples ahead, a useful pattern has three parts:

  1. Initialize a loop variable before the loop starts.
  2. Test that variable in the condition.
  3. Update that variable inside the body so that it moves toward making the condition false.

This pattern is a helpful default, not a universal rule that every while loop must follow. Later in the course we will meet loops that make progress a different way, for instance by reading a fresh value from incoming data on each pass, or by relying on a condition guarded inside the body together with a break rather than a single variable tracked in the header. The three-part pattern is simply the clearest place to start.

The syntax pieces themselves are already familiar: the colon, the indented block, and comparison operators all behave exactly as they did in for loops.

First Example: Counting from 1 to 5

Let's put the three parts to work in the simplest possible loop: printing a message five times.

# Condition checked before each iteration
count = 1
while count <= 5:
    print("Count is", count)
    count += 1  # move toward termination to avoid an infinite loop

Here is how the pattern maps onto the code:

  • count = 1 is the initialization, done before the loop.
  • count <= 5 is the test, checked at the top of every pass.
  • count += 1 is the update, which brings count one step closer to failing the test.

The += operator plays the same role it did in our counters from the previous course, with one key difference: the loop no longer hands us the next value automatically, so we are responsible for advancing it. Running this gives us five lines:

Count is 1
Count is 2
Count is 3
Count is 4
Count is 5

Tracing Execution Step by Step

Predicting a while loop's output is much easier when we trace it one pass at a time. The table below follows the counting loop, showing the condition check, what gets printed, and the value of count after the update.

Checkcount <= 5Printedcount after update
11 <= 5 → trueCount is 12
22 <= 5 → trueCount is 23
33 <= 5 → trueCount is 34
44 <= 5 → trueCount is 45
55 <= 5 → trueCount is 56
66 <= 5 → falsenothing6 (loop ends)

The mental model to carry forward is check, run the body, check again. Notice that the sixth check produces no output: it only ends the loop. Notice, too, that the condition is not reexamined in the middle of the body; once a pass begins, every line in the body runs before the next check happens.

Looping Until a Computed Condition Becomes False

Counters are a gentle start, but while really shines when the loop variable is the data we care about. Suppose we owe 100 and pay 30 each month, and we want to know how long it takes to clear the debt.

# Loop until a computed condition becomes false
balance = 100
month = 0
while balance > 0:
    balance -= 30
    month += 1
    print("Month", month, "balance:", balance)

Two variables share the work here: balance drives termination because it appears in the condition, while month simply counts how many passes happened. Nothing in the code says "four months"; that number comes out of the arithmetic.

Month 1 balance: 70
Month 2 balance: 40
Month 3 balance: 10
Month 4 balance: -20

The fourth pass is worth a close look. At the top of that pass, balance was 10, and 10 > 0 is true, so the entire body ran and pushed the balance to -20. The loop then checked -20 > 0, found it false, and stopped.

Infinite Loops and How to Avoid Them

The update step is not optional decoration. Remove it, and the loop never ends:

count = 1
while count <= 5:
    print("Count is", count)
    # count += 1  <- missing update!

Since nothing ever changes count, the condition 1 <= 5 is true on every single check, and Python keeps printing Count is 1 until we forcibly stop the program. This is an infinite loop, and it is the classic while loop bug. The three usual causes are:

  • The update is missing entirely, as above.
  • The update changes the wrong variable, so the one in the condition stays frozen.
  • The update moves in the wrong direction, for example, count -= 1 with the condition count <= 5.

A quick habit prevents all three: before running a while loop, ask yourself, "What changes in this body, and does that change bring me closer to stopping?" If there is no clear answer, the loop is not ready to run.

Choosing Between While and For

Both loops repeat work, so which one should we reach for? The question is not really about counting passes in advance, since a for loop can just as easily walk through a range(), a file, or any other iterable without anyone knowing ahead of time how many values it will produce. The more useful question is what drives the repetition: are we consuming an iterable item by item, or are we repeating until a condition, tracked in our own variables, changes?

When the job is to walk through a collection, for is the clearer tool, because Python asks the iterable for its next item and handles the advancing for us. Our counting example is honestly a better fit for for, since it is really just walking through range(1, 6):

# Iterable-driven: for is cleaner
for count in range(1, 6):
    print("Count is", count)

# Condition-driven: only while works naturally
while balance > 0:
    balance -= 30

The balance loop is the opposite case: nothing hands us a ready-made sequence of balances to iterate over, so there is no iterable to drive a for loop. The stop condition depends on a value that is computed and changed inside the loop itself, so while expresses it directly. The one-line heuristic: for is generally preferred when consuming an iterable; while is generally preferred when repetition is controlled directly by a condition or changing state.

Conclusion and Next Steps

In this lesson, we met condition-driven repetition. We learned that a while loop checks its Boolean condition before each pass and skips the body entirely if that condition starts out false. We practiced the initialize, test, update pattern that fits counter- and state-driven loops; traced a loop by hand to predict its output; saw why a loop can finish with a negative balance; diagnosed infinite loops and the habit that prevents them; and built a simple rule for choosing between while and for.

Next comes the hands-on part, where we will write counter-driven and value-driven loops, count how many doublings it takes to pass a limit, and rescue a loop that refuses to stop. In the following unit, we will add break, a way to leave a loop the moment we find what we were looking for.

Time to put these loops in motion: let's head to the practice exercises and write some code!

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal