Python has an interesting for statement (reference) which lets you specify an else suite.
In a construct like this one:
for i in foo: if bar(i): break else: baz()
the else suite is executed after the for, but only if the for terminates normally (not by a break).
Here's some code written without for...else:
def contains_even_number(l): "Prints whether or not the list l contains an even number." has_even_number = False for elt in l: if elt % 2 == 0: has_even_number = True break if has_even_number: print "list contains an even number" else: print "list does not contain an even number"
The equivalent code snippet below illustrates how the use of for...else lets you remove an extraneous flag variable from that loop:
def contains_even_number(l): "Prints whether or not the list l contains an even number." for elt in l: if elt % 2 == 0: print "list contains an even number" break else: print "list does not contain an even number"
Use your good judgment when deciding whether to use the for...else construct. It's not unequivocally better, but when there's an asymmetry between the two possibilities, you can make your code more readable by using for...else to keep the "happy path" logic at the top and the exceptional/error case at the bottom.
wow, I never knew this
ReplyDeleteGood post. Thanks
ReplyDeleteOf course you could do:
ReplyDeletefrom __future__ import print_function
contains_even_number = lambda l: print("list contains an even number") if any(elt % 2 == 0 for elt in l) else print("list does not contain an even number")
But this is still useful for lots of things! Thanks!
I've seen this before, and you just gave the first example that made it seem sort of useful, but I still feel like its creepily unintuitive that the else block only executes if the block above it also executes. . .
ReplyDeleteVery interesting, but I agree with ekspiulo - seems a bit unintuitive.
ReplyDeleteFun trivia fact: this language feature was added sometime around the first public release of Python. It's nearly twenty years old!
ReplyDelete