Sometimes for me, it helps to better understand code when broken down into the building blocks. With that said, let's look at how the code branching might look in some rudimentary pseudo-assembler code..
Python:
for i in range(len(haystack)):
print("1")
if haystack[i] == needle:
break
else:
print("2")
print("3")
Pseudo-generated code:
i = 0
for:
GOTO else IF i >= LENGTH(haystack)
PRINT "1"
GOTO break IF haystack[i] == needle
i = i + 1
GOTO for
else:
PRINT "2"
break:
PRINT "3"
Simply put, the else
block will be executed if the loop exhausts the iterable. This, by default, includes any empty (zero-length) iterables. Really, the only way to prevent the else
block from executing is if an explicit break
, return
, exit
or similar is reached within the loop body.