On Sun, 01 Sep 2013 21:58:15 +0200, Antoon Pardon wrote: > Op 31-08-13 02:09, Steven D'Aprano schreef:
>> Adding a fourth option: >> >> for spam in sequence if predicate(spam): >> process(spam) >> >> saves absolutely nothing except a line and an indent level, neither of >> which are in short supply, and gains nothing in readability over Option >> 1. > > So what is the big difference between this situation and the following: > > | else: > | if condition: > | whatever > > which in python we can write: > > | elif condition: > | whatever > > > So either is seems this was a design mistake or a line and an indent > level can be important enough to allow a combination of controls. The difference is that elif is syntax for chaining potentially large numbers of else if clauses: if a: else: if b: else: if c: else: if d: else: It's not uncommon to have, say, a dozen separate elif clauses. Put that inside a method inside a class and you've got an indent of 56 spaces inside the final else block. But that's not really the problem, the real problem is that repeated nesting like this obscures the fact that it is a chain of if...if...if...if and all the if's really should be at the same indentation level. In contrast, you never need to write something like this: for item in seq: if a: if b: if c: if d: ... since that's better written as for item in seq: if a and b and c and d: So a "filtered for" only includes a single if clause. Multiple if clauses don't match the "one line or two" scenario: for item in seq: if cond: <block> elif predicate: <block> else: <block> is not an option. With a single if, filtering the for loop, this is an option: # with or without the first colon for item in seq: if cond: <block> versus: for item in seq: if cond: <block> What's the benefit of the first version? It doesn't make it any more obvious that the for is being filtered. It doesn't keep a whole chain of if clauses together. It doesn't let you do anything that you haven't already done. It just saves an indent and a newline. The cost, on the other hand, includes the risk that people will try to do this: for item in seq: if cond: do_this() do_that() else: do_something else() which is clearly nonsense. Worse is this: for item in seq: if cond: do_this() do_that() else: do_something else() which is still nonsense but won't raise SyntaxError. It would be a Bad Thing if adding a legal else clause to a legal if clause caused a syntax error. But the only way to prevent that is to prohibit the for...if one line version in the first place. *None* of these objections apply to the list comp version of for, where the "block" consists of a single statement before the "for". So despite a superficial (very superficial) similarity between [expr for item in seq if filter] and for item in seq if filter: expr I believe that Python is right to allow the first and prohibit the second. -- Steven -- http://mail.python.org/mailman/listinfo/python-list