The while-else Pattern in Python
Learn Python's unusual while-else loop: the else block runs only when the loop finishes without a break. See how it cleanly handles search-and-not-found situations. Runnable code, a worked example and a quiz.
Key takeaways
- A loop can have an else block that runs only if the loop finishes naturally
- If a break stops the loop early, the else block is skipped
- while-else cleanly expresses search-and-not-found without a found flag variable
- The same else works on for-loops too (for-else)
- Read loop-else as 'else, if we never broke out'
A loop feature most people never learn
You already know how to repeat code with while loops and how to leave a loop early with break. Python has one more loop feature that surprises almost everyone the first time they meet it: a loop can have an else block.
This is not the else of an if statement. A loop's else answers a very specific question: did the loop finish on its own, or was it cut short by a break? Understanding this gives you a clean way to handle "I searched everything and found nothing" — a situation that comes up constantly.
The rule in one sentence
Theelseblock of a loop runs only if the loop finished without hitting abreak.
Let's see it with a simple example:
n = 0
while n < 3:
print("n is", n)
n += 1
else:
print("Loop finished normally")
Output:
n is 0
n is 1
n is 2
Loop finished normally
- The
whileruns whilen < 3, printing0,1,2. - When the condition
n < 3finally becomes false, the loop ends naturally — nobreakwas used. - Because nothing broke out, the
elseruns and prints its message.
Now add a break
Watch what happens when a break interrupts the loop:
n = 0
while n < 3:
print("n is", n)
if n == 1:
print("Breaking out!")
break
n += 1
else:
print("Loop finished normally")
Output:
n is 0
n is 1
Breaking out!
- This time, when
n == 1, thebreakfires and exits the loop immediately. - Because the loop was cut short by a break, the
elseblock is skipped — you never see "Loop finished normally".
That is the entire feature: break skips the else; finishing naturally runs it.
Why this is useful: search and not found
The classic use is searching for something. You loop through possibilities; if you find a match you break. The else is where you handle the case where no match was ever found.
Here we look for a number that divides evenly into 91 (testing whether it is prime):
number = 91
divisor = 2
while divisor < number:
if number % divisor == 0:
print(number, "is divisible by", divisor)
break
divisor += 1
else:
print(number, "is prime")
Output:
91 is divisible by 7
- The loop tries each
divisorfrom 2 upward. - The moment it finds one that divides evenly (
91 % 7 == 0), it prints the factor and breaks. - Because we broke out, the
elseis skipped — we do not claim 91 is prime.
Change number to 97, and no divisor is ever found, so the loop runs to the end and the else declares it prime. The else perfectly captures the "we checked everything and found nothing" outcome.
The same idea without else (the flag pattern)
Before learning loop-else, most programmers solve this with a found flag:
number = 91
found = False
divisor = 2
while divisor < number:
if number % divisor == 0:
found = True
break
divisor += 1
if not found:
print(number, "is prime")
else:
print(number, "is not prime")
This works and is widely understood, but it needs an extra found variable and a separate if afterwards. The loop-else version folds that "not found" check directly into the loop, with no flag. Both are valid; pick whichever reads more clearly.
It works on for-loops too (for-else)
The else clause is not special to while — for loops support it with the exact same meaning:
names = ["Ada", "Brahim", "Chen"]
target = "Maya"
for name in names:
if name == target:
print("Found", target)
break
else:
print(target, "is not in the list")
Output:
Maya is not in the list
- The
forloop scans every name looking fortarget. - It never finds
"Maya", so it finishes naturally and theelsereports the miss.
If the target were "Ada", the loop would break on the first item and the else would be skipped. This for-else pairs beautifully with the searching you do over Python lists in depth.
Worked example: validating a login attempt
Let's give a user three attempts to type a password. If they succeed, we break. If all three attempts fail, the else locks them out.
correct = "swordfish"
attempts = 0
while attempts < 3:
guess = input("Password: ") # imagine the user typing
if guess == correct:
print("Access granted.")
break
attempts += 1
print("Wrong. Attempts used:", attempts)
else:
print("Account locked after 3 failed attempts.")
How it works:
- The loop allows up to three turns because of the condition
attempts < 3. - A correct guess prints "Access granted." and breaks, which also skips the
else— so no lockout message appears. - If the user uses up all three attempts without a correct guess, the loop condition becomes false and the loop ends naturally, triggering the
elselockout.
The else cleanly expresses "they ran out of tries", with no separate counter-checking if afterwards. (To actually run this with real input, see input and output in Python.)
Try it yourself
Write a small "find the first vowel" program:
- Take a word such as
word = "rhythm". - Loop over its characters; if a character is in
"aeiou", print its position andbreak. - Add an
elsethat prints "No vowels found" — and test it on"rhythm", which has none, versus"python", which does.
Then write a guessing-game loop that gives the player five guesses for a secret number, breaking on a correct guess and using else to reveal the answer if they run out. Practise reading every loop-else aloud as "else, if we never broke out".
Quick quiz
Test yourself and earn XP
When does a loop's else block run?
The else runs only when the loop completes normally. A break skips it.
If a break is reached inside the loop, what happens to the else?
break exits the loop AND bypasses the attached else block.
What problem does while-else solve elegantly?
It lets you run code only when the loop searched everything and found nothing, without a separate found flag.
Does the else block work on for-loops too?
Both for and while support an else clause that runs when the loop finishes without a break.
A good plain-English reading of loop-else is…
The else means: the loop ran to the end without any break, so this is the 'nothing interrupted us' case.
FAQ
Because the word else strongly suggests an if statement, and most people read it as 'the loop ran, OR else this'. That mental model is wrong. The else is NOT paired with a condition being false — it is paired with the loop NOT being interrupted by a break. A clearer name would have been 'nobreak'. The trick is to mentally translate every loop-else you read as 'else, if we never broke out'. Once you fix that translation in your head, the feature stops being mysterious and becomes a tidy way to handle the 'searched everything and found nothing' case.
No — use whichever is clearer for the situation. The classic alternative is a boolean flag like found = False that you set to True before breaking, then check after the loop. That pattern is universally understood and works in every language, so it is a perfectly good choice and is often easier for teammates unfamiliar with loop-else to read. Reach for while-else when the loop is genuinely a search and the 'not found' action is short and obvious. If the logic is complex, the explicit flag can be the kinder choice for whoever reads your code next.
Keep exploring
More in Coding