Statham
Statham

Reputation: 4118

Many for in one line in python generator

I can't understand code with multi "for"s in one generator like this, I searched Google and didn't find any answer:

print [j for i in [[1,2],[4,6]] for j in i ]
# will print [1, 2, 4, 6]

print [j for j in i for i in [[1,2],[4,6]] ]
# will print [4, 4, 6, 6]

What is the difference?

How to interpret code like this?

Upvotes: 2

Views: 1533

Answers (4)

chethan
chethan

Reputation: 52

first list comprehension is read as

mat = [[1,2],[4,6]]
a = []
for i in mat:
    for j in i:
        a.append(j)
print(a)

second list comprehension is read as

b = []
for j in i:
    for i in mat:
        b.append(j)
print(b)

Upvotes: 2

Charles Cao
Charles Cao

Reputation: 116

The second generater is error, but in your code scripts, the second generator, the i will be [4, 6] after your run the first generator, so the second will output [4, 4, 6, 6]

Upvotes: 2

Mad Physicist
Mad Physicist

Reputation: 114478

Comprehensions can be interpreted as a shorthand for loops whose only statement is to append an element to the list they create. The syntax you show is how nested loops are implemented.

For example, your first snippet [j for i in [[1,2],[4,6]] for j in i] can be rewritten as

result = []
for i in [[1,2],[4,6]]:
    for j in i:
        result.append(j)

Note that the order of the loops in the comprehension is the same as in the expanded form.

Your second snippet [j for j in i for i in [[1,2],[4,6]] then becomes

result = []
for j in i:
    for i in [[1,2],[4,6]]:
        result.append(j)

As you can see, this will simply fail with a NameError at the start of the first loop since i is not defined at that point.

Upvotes: 1

user1532172
user1532172

Reputation:

Hopefully the expansions will help you reason with the code. It's a lot more readable this way, in my opinion. I'm printing one element at a time instead of the whole list.

print [j for i in [[1, 2], [4, 6]] for j in i]

is equivalent to

for i in [[1, 2], [4, 6]]:
    for j in i:
        print j

As a result i = [4, 6].

Now,

print [j for j in i for i in [[1,2],[4,6]]]

is equivalent to

for j in i: # Remember, i = [4, 6]
    for i in [[1, 2], [4, 6]]:
        print j

Upvotes: 5

Related Questions