AlgoMaster Logo

`while` Loop

High Priority19 min readUpdated June 6, 2026
Listen to this chapter
Unlock Audio

A while loop runs a block of code over and over as long as a condition stays true. You reach for it when you don't know up front how many iterations you'll need: keep retrying until something succeeds, keep prompting the customer until they type a valid value, keep draining a queue of orders until it's empty. for is the right tool when you already know what you're iterating over. while is the right tool when the stopping point depends on something the loop itself discovers.

How while Works

The syntax is small. A while keyword, a condition, a colon, and an indented body:

Python evaluates the condition before every iteration, including the first one. If the condition is true, the body runs. Then control jumps back to the top, the condition is re-tested, and the cycle repeats. The moment the condition is false, the loop ends and execution continues with the line after the loop body.

A few details worth pinning down:

  • The condition is checked before the body runs, not after. If the condition is false on the very first check, the body never runs at all.
  • Anything truthy works as a condition, not just comparisons. while items: runs as long as items is non-empty. while user: runs as long as user isn't None or empty.
  • The body must do something that eventually makes the condition false. If it doesn't, the loop runs forever (more on that below).

Here's the flow Python actually follows:

The loop has three moving parts: the condition, the body, and the state update inside the body that pushes the condition toward false. If any one of these is wrong, the loop misbehaves.

A condition that's false from the very start makes the body skip entirely:

Python checked 0 > 0, got False, and went straight to the line after the loop. The body never ran. This isn't a bug, it's the natural behavior of "check first, then run". If you ever need a loop that runs the body at least once before checking, Python doesn't have a built-in do-while; you build it with a while True loop and an explicit exit, which we'll touch on later.

When to Use while Instead of for

The for loop iterates over a known sequence: a list, a range, a string, anything you can step through one element at a time. The number of iterations is fixed before the loop even starts. while is for the opposite case, where the number of iterations depends on something that happens during the loop.

Here are the situations where while is the natural fit:

  • Polling or retrying. Try an action, and if it fails, try again until it succeeds or you've used up your attempts.
  • Processing a queue or stack until empty. You don't know how many items will end up in there, and the loop itself may add more.
  • Validating user input. Keep asking until the customer types something that passes your checks.
  • Consuming a stream. Read values one at a time until you hit the end of the data.
  • Simulations and search. Iterate until a state condition is reached, like "the cart total exceeds the free-shipping threshold" or "we've found a matching product".

Here's a quick comparison so you can pick the right tool fast:

SituationUse
Iterate over a known list, string, or rangefor
Repeat a fixed number of timesfor with range(n)
Loop until a condition becomes truewhile
Drain a collection that may grow during the loopwhile
Retry until success or attempt limitwhile
Read input until a sentinel valuewhile

A draining example shows the difference clearly. Imagine a list of pending orders that we process one at a time:

You could have written this with a for loop over pending_orders, but the moment another part of the system can append new orders into the queue while you're processing it, for becomes awkward and while reads naturally. The condition while pending_orders: is true as long as the list has anything in it, and Python re-checks it after every pop(0).

A retry example is the second classic case. We want to attempt a payment up to three times before giving up:

Two things make this a while loop and not a for loop. First, the stopping condition combines two things: an attempt limit and a success flag. Second, on a successful attempt we want to stop early, not keep going through the remaining tries. A for attempt in range(max_attempts) could be made to work, but the boolean condition reads more directly here.

The Loop Variable Idiom

Most while loops follow the same shape: a variable is initialized before the loop, the condition checks that variable, and the body updates it. Together, these three pieces are called the loop variable idiom.

The three pieces:

  1. Initialization before the loop: stock_remaining = 5. This sets the starting state.
  2. Condition at the top: stock_remaining > 0. This decides whether to run the body.
  3. Update inside the body: stock_remaining -= 1. This pushes the state toward making the condition false.

If you forget any one of these, the loop won't behave the way you expect. Forget the initialization and you get a NameError. Forget the condition update inside the body, and you get an infinite loop. Make the update go the wrong way, and the loop also runs forever.

Here's what the missing-update bug looks like:

What's wrong with this code?

This loop never ends. Python prints Packing an item forever because items_to_pack stays at 3 and 3 > 0 is always true. You'd have to interrupt the program manually (Ctrl+C in a terminal). The fix is to update the variable inside the body:

This is the single most common while-loop bug. Whenever you write a while, immediately ask yourself: "What inside the body changes the condition?" If you can't answer, the loop is broken.

The loop variable doesn't have to be a counter. It can be any value the condition examines. A list, a string, an object, a flag, anything. As long as the body changes it in a way that eventually makes the condition false, the pattern works.

The variable here is a string, the condition checks its last character, and the body trims one character off the end every iteration. After three iterations, the condition is false and the loop stops. This is just the loop variable idiom with a different shape.

Sentinel-Driven Loops

A sentinel is a special value that signals "stop". Instead of counting iterations or shrinking a collection, you keep going until you encounter the sentinel. This pattern shows up whenever you process items one at a time and the data itself tells you when you're done.

A common case is processing orders until you find one that was cancelled, treating the cancellation as a stopping marker:

The sentinel here is the string "cancelled". The loop keeps going as long as the current order's status isn't the sentinel. Notice the structure: we read the first value before the loop, and we read the next value at the bottom of the body so the condition can check it on the next iteration.

This shape is sometimes called the "loop and a half" because the first read happens outside the loop and the rest happen inside. It's a known awkwardness and one of the reasons Python added the walrus operator, which makes some while-loop patterns shorter.

A sentinel can also come from the outside, like user input. Here we keep accepting product names from the customer until they type "done":

A possible run might look like:

Same pattern again: read once before the loop so the condition has something to check, and read again at the end of the body to set up the next check. The sentinel "done" is part of your input contract with the user, not a value you'd ever want to store in the wishlist.

The choice of sentinel matters. It must be a value that can never legitimately appear in the real data. "done" works for product names because no real product is called "done". An empty string or None works for many cases. A negative number works for prices. If your sentinel can collide with real data, you'll silently truncate valid input.

Validating User Input

Input validation is one of the most natural places to use while. You don't know how many tries the customer will take, so you keep prompting until the answer is acceptable.

A simple example: ask for a positive quantity to add to the cart.

A possible run:

The initial value quantity = -1 is a small trick to make sure the loop runs at least once. Any value that fails the condition would do. The body asks for input, validates it, and only updates quantity to a value that passes when the input is good. As long as the input is bad, quantity stays at -1 and the loop tries again.

There's a more readable alternative using while True and an explicit exit using break. For now, the version above is enough to handle most validation cases without needing those keywords.

A second validation example handles email format checks:

A possible run:

The condition combines two checks with or: the email is bad if it lacks @ or lacks .. The loop keeps going until both characters are present. Real email validation is much harder, but the pattern of "loop until input passes a check" is the same.

while True with an Explicit Exit

Sometimes the most natural place to decide "we're done" is in the middle of the body, not at the top. For those cases, you write while True: and exit explicitly when the right thing happens.

while True makes the condition trivially true forever. The actual stopping logic lives inside the body, with a keyword that breaks out of the loop.

The reason this pattern is sometimes preferred over a regular while condition: is that it avoids the loop-and-a-half awkwardness from the sentinel section. You don't have to read a value before the loop and again inside the body. You read once, decide once, and exit cleanly when the condition is met.

while True is also how you'd build a do-while loop in Python. There's no built-in keyword for "run the body once before checking", but the same effect is easy to get with this pattern.

A summary of when each form makes sense:

FormBest for
while condition:Standard case where the test naturally lives at the top
while True: with an exitThe decision to stop happens in the middle of the body
while collection:Drain a list, set, or dict until empty
while flag:Stop when a boolean signal flips

Common Mistakes

Most while-loop bugs fall into a few familiar shapes. Recognizing them early saves a lot of debugging time.

Forgetting to update the loop variable. Already covered above, but worth repeating because it's the number-one mistake. Every while loop needs something in the body that changes the condition.

This runs forever. The fix is one line.

Off-by-one errors. Choosing < versus <= decides whether the boundary value is included. Both are correct in different situations, so think about what you actually want.

This prints 0 through 4, five values. If you wanted 1 through 5, you'd write n = 1 and while n <= 5. The classic mistake is mixing them up and getting either one too few or one too many iterations.

Using `while` where `for` is cleaner. A loop with a counter from 0 to n-1 is almost always clearer as a for loop:

Both produce the same output, but the for version doesn't need an index variable, doesn't need a manual increment, and can't have an off-by-one error. Reach for while when there's a real reason: an unknown number of iterations, a non-numeric stopping condition, a mutating collection. Otherwise prefer for.

Conditions that depend on side effects you didn't expect. If the body modifies something that the condition reads, it's easy to get a surprise.

This loop adds a sticker forever because every iteration grows the cart. The condition len(cart) > 1 was meant to say "shrink until almost empty", but the body grows the list instead. Always trace through the first few iterations on paper to make sure the body actually pushes the condition toward false, not away from it.

Comparing floats with equality. Floats accumulate small rounding errors, so a while x == 0.5: style check can miss the target completely. Use <, >, or a tolerance comparison instead:

The loop runs one more time than you might expect because of how floating-point addition rounds. If you want exactly ten iterations, count with an integer (while step < 10:) and compute the float from the counter inside the body. The lesson here is to keep float arithmetic out of loop conditions when integer math would do.

Quiz

while Loop Quiz

9 quizzes