Nested list comprehensions

I tried to use the value of an outer list comprehension in an inner one:

[ x for x in range(y) for y in range(3) ]

But unfortunately this raises a NameError because the name y is unknown (although the outer list comprehension specifies it).

Is this a limitation of Python (2.7.3 and 3.2.3 tried) or is there a good reason why this cannot work?

Are there plans to get rid of the limitation?

Are there workarounds (some different syntax maybe I didn’t figure out) to achieve what I want?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You are talking about list comprehensions, not generator expressions.

You need to swap your for loops:

[ x for y in range(3) for x in range(y) ]

You need to read these as if they were nested in a regular loop:

for y in range(3):
    for x in range(y):
        x

List comprehensions with multiple loops follow the same ordering. See the list comprehension documentation:

When a list comprehension is supplied, it consists of a single expression followed by at least one for clause and zero or more for or if clauses. In this case, the elements of the new list are those that would be produced by considering each of the for or if clauses a block, nesting from left to right, and evaluating the expression to produce a list element each time the innermost block is reached.

The same thing goes for generator expressions, of course, but these use () parenthesis instead of square brackets and are not immediately materialized:

>>> (x for y in range(3) for x in range(y))
<generator object <genexpr> at 0x100b50410>
>>> [x for y in range(3) for x in range(y)]
[0, 0, 1]

Method 2

Did you try:

[x for y in range(3) for x in range(y)]

Because that produces an output… This produces:

[0, 0, 1]

Which may or may not be what you wanted….

Method 3

just nest another gen.

[ x for x in [range(y) for y in range(3) ]]

gives me:

[[], [0], [0, 1]]


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x