VMware ESXi and vSphere Cluster Management

Using else Statements with for and while Loops in Python

Learn how Python loop else clauses work with for and while loops, including break, searching, nested loops, continue, pass, return, and exceptions.

What does else mean after a loop?

Python allows an optional else clause to be attached directly to a for or while statement. This is a loop feature, not an if/else statement nested inside the loop.

The loop's else suite runs when the loop finishes normally. In practical terms, it is best understood as a no-break clause: it runs only when the associated loop ends without executing break.

Normal completion means different things for the two loop types:

  • A for loop completes normally when its iterable has no more values.
  • A while loop completes normally when its condition becomes false.

An else clause does not run if break terminates its associated loop.

Basic syntax

The else aligns with the for or while, not with code inside the loop.

for item in iterable:
    # Loop body
    print(item)
else:
    # Runs if the loop did not use break
    print("Loop completed without break")

while condition:
    # Loop body
    do_work()
else:
    # Runs if the loop did not use break
    print("Loop completed without break")

How a for...else loop behaves

A for loop processes each value supplied by an iterable. An iterable is an object that can provide values one at a time, such as a string, list, tuple, range, or dictionary.

Normal completion after every character

This loop processes every character in the string. After the string is exhausted, the else suite runs.

word = "python"

for character in word:
    print(character)
else:
    print("Every character was processed")

There is no break, so the loop reaches normal completion and prints the completion message.

Breaking when a target is found

Here, break immediately exits the nearest enclosing loop when the target character is found. Because the loop exits through break, its else suite is skipped.

word = "python"
target = "h"

for character in word:
    if character == target:
        print("Found", target)
        break
else:
    print("The target was not found")

If target is changed to "z", no break executes. The string is exhausted, so the loop's else prints the not-found message.

An empty iterable

An empty iterable counts as normal completion. The loop body runs zero times, but the loop still finishes without a break, so the else suite runs.

values = []

for value in values:
    print(value)
else:
    print("No break occurred")

If an empty input needs a different meaning in your program, handle that case separately before or around the loop.

How a while...else loop behaves

A while loop repeats while its Boolean condition is true. It completes normally when that condition eventually becomes false.

Normal completion with a counter

This counter is updated during every iteration. When count < 3 becomes false, the loop ends normally and the else suite runs.

count = 0

while count < 3:
    print("count:", count)
    count += 1
else:
    print("The counter reached the limit")

Updating the loop state is essential. If count were never changed, the condition could remain true forever and the loop would never reach its else.

Early termination with break

This loop normally processes values while the index is valid, but it stops early when it encounters a negative number.

values = [4, 7, -1, 9]
index = 0

while index < len(values):
    value = values[index]
    if value < 0:
        print("Negative value found")
        break
    print("Processed", value)
    index += 1
else:
    print("All values were processed")

Because the negative value causes break, the else suite does not run.

An initially false condition

If a while condition is false before the first test of the body, the loop has completed normally. Therefore, its else suite runs even though the body ran zero times.

temperature = 0

while temperature > 10:
    print(temperature)
    temperature -= 1
else:
    print("The condition was false")

Using loop else for searching

Searching is the most common practical use of loop else. The pattern is:

  1. Inspect each item.
  2. Use break when a match is found.
  3. Use the loop else to handle the case where no match was found.

The else belongs to the loop and indicates that no break occurred.

numbers = [12, 5, 18, 21]
requested = 18

for number in numbers:
    if number == requested:
        print("Found", requested)
        break
else:
    print(requested, "was not found")

When requested is 18, the loop breaks and the not-found message is skipped. When it is 99, the list is exhausted without a break, so the else message runs.

This pattern also works with collection members and other tests:

names = ["Amina", "Leo", "Marta"]
requested_name = "Leo"

for name in names:
    if name == requested_name:
        print("Member found:", name)
        break
else:
    print("Member not found:", requested_name)

How other control-flow statements interact with loop else

continue

continue skips the remaining code in the current iteration and starts the next iteration. It does not terminate the loop. If the loop later completes normally, its else still runs.

values = [1, 2, 3, 4]

for value in values:
    if value % 2 == 0:
        continue
    print("Processed odd value:", value)
else:
    print("The loop finished without break")

pass

pass performs no action. It is a placeholder where Python requires a statement; it does not skip to the next iteration, end the loop, or suppress the loop else.

for value in [1, 2, 3]:
    if value == 2:
        pass
    print(value)
else:
    print("Loop completed")

Do not confuse pass with break. Use break to exit the loop, and use continue to skip to the next iteration.

return

return exits the surrounding function immediately. Since execution leaves the function, the loop's else suite is not reached.

def find_positive(values):
    for value in values:
        if value > 0:
            return value
    else:
        print("No positive value found")
        return None

When a positive value is found, return exits the function before the loop can reach its else.

Exceptions

An uncaught exception leaves normal control flow. Therefore, the loop's else suite is not reached if an exception escapes the loop.

for text in ["10", "not a number", "30"]:
    number = int(text)
else:
    print("All text was converted")

The invalid conversion raises an exception. Unless it is caught, execution stops before the loop's else.

Loop exit paths at a glance

Loop exit pathDoes the loop else clause run?Reason
for iterable exhaustedYesThe loop completed normally.
while condition becomes falseYesThe loop completed normally.
break executesNobreak exits the associated loop.
continue executes but the loop later completesYescontinue does not exit the loop.
Empty iterableYesThere is no iteration and no break.
while condition false before the first iterationYesThe loop completes normally with zero iterations.
return from the surrounding functionNoExecution leaves the function first.
Uncaught exceptionNoNormal control flow is interrupted.

Nested loops and else attachment

A nested loop is a loop placed inside another loop. Each else attaches to the loop at the same indentation level. Also, break exits only the nearest enclosing loop.

for row in [1, 2]:
    print("Outer row:", row)

    for column in [1, 2, 3]:
        if row == 1 and column == 2:
            print("Break the inner loop")
            break
        print("  Inner column:", column)
    else:
        print("  Inner loop completed without break")

else:
    print("Outer loop completed without break")

For the first row, the inner loop breaks at column 2, so the inner else is skipped. The outer loop continues with the next row because the inner break does not affect the outer loop. For the second row, the inner loop finishes normally, so its else runs. The outer loop itself never breaks, so the outer else also runs at the end.

Trace nested loops separately when debugging: identify which loop each break belongs to, then check which else is aligned with that loop.

Correct indentation and readability

Indentation determines whether else belongs to an if or a loop.

for item in items:
    if item == target:
        print("Found")
        break
else:
    # This else belongs to for
    print("Not found")

The loop else is aligned with for. An else indented under the loop body would belong to the nested if instead.

Use clear variable names such as requested_name, candidate, or match_found. A short comment can make the no-break meaning clear when the pattern is unfamiliar.

# The else runs only when no candidate matched.
for candidate in candidates:
    if candidate == requested:
        result = candidate
        break
else:
    result = None

Common misconceptions and troubleshooting

“The else ran even though the loop body never ran.”

This is expected for an empty iterable or an initially false while condition. Both are normal completion. If empty input should produce a different result, test for it explicitly.

“The else did not run after finding an item.”

The search probably used break. Put the found-item handling before break, and reserve the loop else for the not-found case.

“The else looks associated with the wrong statement.”

Check indentation. Align a loop else with its for or while. Align an if else with its if.

“A while loop never reaches else.”

Check whether the loop's state is updated so the condition can become false. Also check for break, return, and exceptions that may provide another exit path.

“A nested-loop else behaves unexpectedly.”

Remember that break exits only the innermost active loop, while each else belongs to the loop at its matching indentation level. Use helper functions if nested control flow becomes difficult to follow.

“pass stopped the loop.”

pass does nothing. Use break to exit a loop or continue to skip the rest of the current iteration.

Control-flow statement comparison

StatementEffect on current iterationEffect on loopEffect on loop else
breakStops the current iteration immediatelyExits the nearest enclosing loopPrevents that loop's else
continueSkips the remaining bodyStarts the next iterationDoes not prevent else if the loop later completes
passDoes nothingDoes not change loop executionDoes not suppress else
returnStops execution of the functionLeaves the loop and functionThe loop else is not reached

Summary

  • Python permits an optional else clause after both for and while loops.
  • The loop else runs after normal completion, meaning no break exited that loop.
  • A for loop completes normally when its iterable is exhausted.
  • A while loop completes normally when its condition becomes false.
  • Empty iterables and initially false conditions still allow the loop else to run.
  • break skips the associated loop else; continue and pass do not.
  • return and uncaught exceptions leave normal control flow before the loop else can run.
  • The search pattern—break on a match, loop else for no match—is the most common practical use.
  • In nested loops, break affects only the innermost loop, and indentation shows which loop an else belongs to.