kezzos kezzos - 1 year ago 44
Python Question

Duplicating list items variable number of times with list comprehension

I am basically trying to get my head around using a list comprehension with this basic bit of code. Im trying to duplicate a list item by the value of the list item:

y = [1, 2, 0, 1]
x = []
for i in y:
for j in range(i):
# Desired output
>>> [1, 2, 2, 1]

x = [i for _ in range(i) for i in y]
# Wrong output
>>> [1, 2, 0, 1]

# Right output
x = [j for j in y for _ in range(j)]
>>> [1, 2, 2, 1]

I just cant seem to get my head around why I get the wrong output for the second example. Could someone explain what is wrong here. Thanks.

Answer Source

When you have multiple for loops inside a list comprehension, the loops are processed in the same order as they would be using "traditional" for loops. Your list comp that gives the correct output has the loops in the same order as your code at the start using .append with traditional for loops.

As Rahul mentions in the comments, in isolation,

x = [i for _ in range(i) for i in y]

would give a

NameError: name 'i' is not defined

It doesn't in this case because i was defined by the earlier code.

In contrast, look at what happens with a nested list comp:

y = [1, 2, 0, 1]
x = [[j for j in range(i)] for i in y]


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

Here, the outermost loop is in the outer comprehension and the inner loop is in the inner comprehension. So for each iteration of the for i in y we create a new list comp, and in that list comp we loop over range(i).