Loop else: run only if the loop wasn't broken out of
The else block on a loop runs when the loop finishes normally, meaning the iterator was exhausted (for) or the condition became false (while), and it is skipped if the loop is left through break. The best mental model is 'no-break': else is attached to the loop's break, not to the loop condition, which is why the keyword is widely considered poorly named. Its purpose is the search pattern: loop looking for something, break when found, and let else handle 'not found' without a flag variable.
Precise semantics worth stating in an interview: else runs on normal exhaustion, including when the iterable is empty; it does not run after break, return, or an uncaught exception; continue does not prevent it. A common wrong belief is that else means 'the loop body never executed', which is false.
Trade-offs: loop-else removes a found = False flag and keeps search logic in one place, but many readers find it surprising, so I use it sparingly and with a short comment. Alternatives are often clearer: any() or all() for yes/no, next(generator, default) for first match, or extracting a helper function that uses return. I keep for-else when there are nested loops or complex bodies where those alternatives would be awkward. Linters and some style guides discourage it, so follow your team's conventions. This construct has been unchanged across Python 3.
0-2 years experience
2-5 years experience
5-8 years experience
8+ years experience