DEV Community

Cover image for Python by Structure: The For/Else Block You Didn't Know Existed
Aaron Rose
Aaron Rose

Posted on

Python by Structure: The For/Else Block You Didn't Know Existed

"Margaret," Timothy said, looking up from his code, "I learned about try/else from you yesterday. But I just saw else after a for loop. That can't be right, can it?"

Margaret smiled. "Python has a fondness for the else clause. It appears in more places than most developers realize. Let me show you why for/else exists and when it's useful."

Timothy pulled up the code he'd been reading - a function to find a user by ID:

def find_user(user_id, users):
    found = False
    result = None

    for user in users:
        if user['id'] == user_id:
            found = True
            result = user
            break

    if not found:
        print(f"User {user_id} not found")
        return None

    return result
Enter fullscreen mode Exit fullscreen mode

"See all these extra variables?" Timothy pointed at found and the separate check afterward. "It feels clunky. There must be a better way."

The Problem: Flag Variables Everywhere

"There is," Margaret said. "The else clause on loops solves exactly this problem. Watch."

She rewrote the function:

def find_user(user_id, users):
    for user in users:
        if user['id'] == user_id:
            return user
    else:
        print(f"User {user_id} not found")
        return None
Enter fullscreen mode Exit fullscreen mode

"Wait," Timothy frowned. "That else is attached to the for loop, not the if statement?"

"Exactly. Let me show you the structure."

Tree View:

find_user(user_id, users)
    For user in users
        If user['id'] == user_id
            Return user
    Else
        print(f'User {user_id} not found')
        Return None
Enter fullscreen mode Exit fullscreen mode

English View:

Function find_user(user_id, users):
  For each user in users:
    If user['id'] == user_id:
      Return user.
  Else:
    Evaluate print(f'User {user_id} not found').
    Return None.
Enter fullscreen mode Exit fullscreen mode

Timothy studied the structure carefully. "The else sits at the same level as the for loop... So it runs when the loop finishes?"

"Almost," Margaret said. "It runs when the loop finishes naturally - without hitting a break or return. If you find what you're looking for and exit early, the else never runs."

"Oh!" Timothy's eyes widened. "So else here means 'if we searched everything and found nothing.'"

"Precisely. The structure shows it clearly - the else is part of the loop's control flow, not part of the if statement inside."

Understanding the Pattern

Margaret pulled out another example to drive the point home:

def validate_all_positive(numbers):
    for num in numbers:
        if num <= 0:
            print(f"Found invalid number: {num}")
            return False
    else:
        print("All numbers are positive!")
        return True
Enter fullscreen mode Exit fullscreen mode

Tree View:

validate_all_positive(numbers)
    For num in numbers
        If num <= 0
            print(f'Found invalid number: {num}')
            Return False
    Else
        print('All numbers are positive!')
        Return True
Enter fullscreen mode Exit fullscreen mode

English View:

Function validate_all_positive(numbers):
  For each num in numbers:
    If num <= 0:
      Evaluate print(f'Found invalid number: {num}').
      Return False.
  Else:
    Evaluate print('All numbers are positive!').
    Return True.
Enter fullscreen mode Exit fullscreen mode

"Now I see it," Timothy said. "The else block is the 'success case' - it only runs if we checked every number without finding a problem."

"That's the pattern," Margaret confirmed. "Search loops benefit most from for/else. Without it, you need flag variables like your found boolean. With it, the structure expresses your intent directly: 'loop through these items, and if we never exit early, do this.'"

Timothy looked back at his original code with the flag variable. "So all those found = False and if not found: checks are just working around not knowing about for/else?"

"Most of them, yes. Python gives you the structural tool to express 'search succeeded' versus 'search failed' without extra variables cluttering your logic."

"Does this work with while loops too?" Timothy asked.

"It does. Any loop in Python can have an else clause. Same rule applies - it runs only if the loop completes without break or return."

Timothy saved his refactored function, already thinking about other search loops in his codebase. "First try/else, now for/else. What other else clauses is Python hiding?"

Margaret laughed. "Those are the main ones. Python's consistent here - else always means 'if the primary path didn't exit early.' Whether that's 'no exception raised' or 'loop completed naturally,' the principle is the same."

"The structure is the logic underneath," Timothy repeated Margaret's phrase from yesterday. "Once you see the pattern, it shows up everywhere."

"Now you're learning to think structurally," Margaret said, returning to her desk with a satisfied smile.


Explore Python structure yourself: Download the Python Structure Viewer - a free tool that shows code structure in tree and plain English views. Works offline, no installation required.

Python Structure Viewer


Aaron Rose is a software engineer and technology writer at tech-reader.blog and the author of Think Like a Genius.

Top comments (0)