← Home

051. Loop Else Clause

Signal loop completion without early exit

051. Loop Else Clause

Aryan’s RAM monitor needs to search the running process list for any process whose memory usage exceeds a threshold. If it finds one, it alerts immediately. If it scans all processes and none exceed the threshold, it should log “All clear”.

His first attempt uses a boolean flag:

found = False
for proc in processes:
    if proc["rss_mb"] > threshold:
        print(f"ALERT: {proc['name']} using {proc['rss_mb']:.0f} MB")
        found = True
        break
if not found:
    print("All clear")

A senior dev shows him the for/else pattern — it’s exactly what the flag was for:

for proc in processes:
    if proc["rss_mb"] > threshold:
        print(f"ALERT: {proc['name']} using {proc['rss_mb']:.0f} MB")
        break
else:
    print("All clear")  # only runs if no break fired

The else block runs only when the loop exhausts without hitting break. If break fires, else is skipped entirely. This is the built-in “not found” signal.

Why it matters in the RAM manager: Aryan checks a dozen conditions per process (high RSS, high VMS, zombie state, banned process names). Without for/else, he’d need a flag variable for each one. With for/else, each check is self-contained.


💡 Fun fact: Python’s for/else and while/else are almost unique in mainstream programming languages — virtually no other language has this construct. It was present in Python from the very beginning (Python 0.9, circa 1991) and was modeled after a similar feature in ABC, Python’s predecessor. Most experienced Python developers consider it one of the language’s best-kept secrets for writing clean search loops.

⚠️ Watch out: The else keyword here is misleading — it doesn’t mean “otherwise the condition was False.” It means “the loop finished without hitting break.” Many beginners read for x in items: ... else: ... and think the else runs when the list is empty or when the condition was never true, when in reality an empty list also triggers the else (the loop “completes” immediately).

🤔 Think about it: for/else eliminates the need for a boolean flag variable. But boolean flags are simple and universally understood across all languages. When would you choose for/else over a flag in a team codebase — and does the answer change if half your team comes from Java or Go backgrounds?

Learning objectives

  • Use for/else to detect loop completion without break
  • Apply the pattern for “not found” scenarios
  • Understand when for/else is clearer than a flag variable

Key concepts

  • loop else
  • for else
  • break
  • search pattern

Try it

Concept detail

Python’s for/else (and while/else) is unique: the else block runs when the loop completes normally (no break). It signals “loop finished without finding what we sought”.

Pattern: for item in collection: if condition: break else: # only reached if no break fired

Why for/else is better than a flag variable:

flag style — works but adds noise

found = False for x in items: if x == target: found = True break if not found: handle_missing()

for/else — intent is explicit

for x in items: if x == target: break else: handle_missing()

Use cases: searching for a condition that may or may not exist in a collection. The else clause is often confusingly named — think of it as “no break happened”.

Solution

import math

def is_prime(n):
    if n < 2:
        return False
    for i in range(2, int(math.sqrt(n)) + 1):
        if n % i == 0:
            return False
    return True

def find_first_prime_after(start):
    n = start + 1
    while True:
        for i in range(2, int(math.sqrt(n)) + 1):
            if n % i == 0:
                break
        else:
            return n
        n += 1

Tests

def test_prime_2():
    assert is_prime(2) == True

def test_prime_7():
    assert is_prime(7) == True

def test_not_prime_1():
    assert is_prime(1) == False

def test_not_prime_4():
    assert is_prime(4) == False

def test_prime_11():
    assert is_prime(11) == True

def test_first_prime_after_10():
    assert find_first_prime_after(10) == 11

def test_first_prime_after_20():
    assert find_first_prime_after(20) == 23

Resources