[Python-ideas] With clauses for generator expressions

Terry Reedy tjreedy at udel.edu
Thu Nov 15 19:36:45 CET 2012

On 11/15/2012 10:25 AM, Andrew Barnert wrote:
> From: Nick Coghlan <ncoghlan at gmail.com>
> Sent: Thu, November 15, 2012 4:39:42 AM
>> On Thu, Nov 15, 2012 at 9:11 PM, Andrew Barnert <abarnert at yahoo.com> wrote:
>> One, and only one, clause in a comprehension or generator expression is written
>> out of sequence: the innermost clause is lifted out and written first.

This is how list comps were designed and initially defined.

> Given that there are only three clauses,
 > "flatten in order, then move expression to front"

This is the simple and correct rule.

> and "flatten in reverse order, then move if clause to back"

This is more complicated and wrong.

> are identical.

Until one adds more clauses.

> I suppose you're right that, given that the rule for nested
> expressions is to preserve the order of nesting, the first description is more
> natural.
> But at any rate, I don't think any such rule is what most Python programmers
> have internalized.

It *is* the rule, and a very simple one. The reference manual gives it, 
though it could perhaps be clearer. The tutorial List Comprehension 
section does give a clear example:
For example, this listcomp combines the elements of two lists if they 
are not equal:

 >>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
and it’s equivalent to:

 >>> combs = []
 >>> for x in [1,2,3]:
...     for y in [3,1,4]:
...         if x != y:
...             combs.append((x, y))
 >>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
Note how the order of the for and if statements is the same in both 
these snippets.

> People obviously know how to nest clauses in general (we
> couldn't speak human languages otherwise), but they do not know how to write, or
> even read, nested comprehensions. What they know is that there are three
> clauses, and they go expression-for-if, period. And those who do learn about
> nesting seem to guess the order wrong at least half the time (hence all the
> StackOverflow posts on "why does [x for x in range(y) for y in range(5)] give me
> a NameError?").

Anyone who read and understood that snippet in the tutorial, which took 
me a minute to find, would not ask such a question. There are people who 
program Python without ever reading the manuals and guess as they go 
and, when they stumble, prefer to post questions on forums and wait for 
a customized answer rather than dig it out themselves.

Terry Jan Reedy

More information about the Python-ideas mailing list