Reputation: 4118
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
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
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
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
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