2011-12-16

Explaining For/Else In Python

In response to a thread on G+ I've decided to write a this article on 'how for/else works'.

I should start by saying that this isn't intuitive or simple. It's quite complicated, but it has a very clear use case. Let me start by stating as simply as I can the use-case.

for element in seq:
    if somecondition(element):
         dosomething(element) 
         break
else: 
     dosomething(defaultinput)

I think that example is reasonably clear, but it's important to explain what's happening here.

If a 'for' loop does not break, it's else is run, otherwise the else is not run. So:

  • The else suite is run if:
    • the sequence is empty
    • break is never executed
  • The else suite is bypassed if:
    • break is executed
    • a return statement in the loop is executed
    • an exception raises in the for loop

I hope that's clear. Any comments or addendums or errors I've made, please let me know in the comments.

Edit: I don't think using an 'else:' on a for loop is a bad idea. But I think it should only be used in exactly the idiom presented in the example, anything with more complicated flow control or more than 8 lines should be re-factored to use a function call with 'return' in the appropriate places.

3 comments:

Anonymous said...

The example works but it would probably be more useful to describe why this is extremely bad style and should be avoided, wouldn't it?

geoffrey said...

It should be a syntax error to use else: without a comment on the line saying "WARNING: else doesn't mean what you probably think it does."

Marien Zwart said...

Is this language feature really disliked this much? I use it a lot and it does exactly what I think it does: if the end of the loop ("for" and "while" both support this) is reached without hitting "break", the "else" clause runs. Which is useful for finding an interesting element and doing something else (like complaining) if it's missing.

What's tripping people up? Are you expecting the "else" to only run if the loop body never executed?