Blog Post #40: An Unusual Feature: The else Block in Loops

We’ve spent the last two posts learning how to control the flow inside our loops with break (Post #38) and continue (Post #39). Now, we’re going to look at a unique and somewhat surprising feature of Python’s loops that you won’t find in many other languages: the optional else block.

This isn’t the same else you know from if statements, and its behavior is a bit different. In this post, you’ll learn how the for...else and while...else constructs work and their primary, elegant use case.

The Loop else Clause: What Does It Do?

An else block attached to a for or while loop has a very specific trigger: it only runs if the loop completes its full, natural course without being terminated by a break statement.

Think of it this way:

  • If the loop finishes normally (a for loop runs out of items, or a while loop’s condition becomes False), the else block will run.
  • If the loop is exited prematurely with a break statement, the else block will be skipped.

The for...else Statement in Action

The most common and useful application of this feature is in search operations. The for loop searches for an item, and the else block can handle the “not found” case.

Case 1: The Loop is Broken (Item Found)

Let’s search a list for a number. In this case, the number exists in the list.

numbers = [1, 5, 12, 43, 98]
number_to_find = 43

for number in numbers:
    if number == number_to_find:
        print(f"Success! Found the number: {number_to_find}")
        break
else:
    # This block will NOT run
    print("The number was not found in the list.")

The output is Success! Found the number: 43. Because the break statement was executed, the else block was skipped.

Case 2: The Loop Completes Naturally (Item Not Found)

Now, let’s search for a number that isn’t in the list.

numbers = [1, 5, 12, 43, 98]
number_to_find = 44 # This number is not in the list

for number in numbers:
    if number == number_to_find:
        print(f"Success! Found the number: {number_to_find}")
        break
else:
    # This block WILL run
    print(f"Failure. The number {number_to_find} was not found.")

The output is Failure. The number 44 was not found.. The for loop iterated through every item, the if condition was never met, and break was never called. Because the loop completed its full course, the else block was executed.

The while...else Statement

The logic is identical for while loops. The else block runs if the while loop’s condition becomes False, but is skipped if the loop is exited via break.

Here is a countdown that completes normally:

count = 3
while count > 0:
    print(count)
    count -= 1
else:
    # This block WILL run
    print("Countdown finished successfully.")

Output: 3, 2, 1, Countdown finished successfully.

Here is a countdown that is aborted:

count = 5
while count > 0:
    print(count)
    if count == 3:
        print("Aborting countdown!")
        break
    count -= 1
else:
    # This block will NOT run
    print("Countdown finished successfully.")

Output: 5, 4, 3, Aborting countdown!

Why Bother? A Cleaner Alternative to Flags

You might be thinking, “I could just use a boolean flag variable to track if I found something.” And you’d be right. Before the loop...else construct, you would write code like this:

found_it = False
for number in numbers:
    if number == number_to_find:
        found_it = True
        break

if not found_it:
    print("The number was not found.")

This works, but it requires an extra found_it variable to manage. The for...else construct provides a cleaner, more direct way to express the same logic without the need for a separate flag.

What’s Next?

The loop else clause is a unique feature of Python. While not used every day, it’s a very elegant tool for handling logic that needs to distinguish between a loop finishing naturally and a loop being broken prematurely, especially in search algorithms.

We’ve now covered all the fundamental control statements for loops (break, continue, and else). Just as we saw with if statements in Post #29, we can also place loops inside other loops. In Post #41, we will explore the powerful and sometimes tricky concept of nested loops.

Author

Debjeet Bhowmik

Experienced Cloud & DevOps Engineer with hands-on experience in AWS, GCP, Terraform, Ansible, ELK, Docker, Git, GitLab, Python, PowerShell, Shell, and theoretical knowledge on Azure, Kubernetes & Jenkins. In my free time, I write blogs on ckdbtech.com

Leave a Comment