Repeat each item in a list a number of times specified in another list
numpy's repeat
function gets the job done:
>>> import numpy as np
>>> x = [2, 3, 4]
>>> y = [1, 2, 3]
>>> np.repeat(x, y)
array([2, 3, 3, 4, 4, 4])
-
You can use list comprehension, like this
>>> x = [2, 3, 4] >>> y = [1, 2, 3] >>> [item for item, count in zip(x, y) for i in range(count)] [2, 3, 3, 4, 4, 4]
Here, we
zip
thex
andy
so that the element fromx
and its corresponding count fromy
are grouped as a single tuple. Then, we iteratecount
number of items to produce the same item. -
If your objects in
x
are immutables, then you can createcount
copies of the same and put them together in a list, like this>>> [i for item, count in zip(x, y) for i in [item] * count] [2, 3, 3, 4, 4, 4]
-
You can do the same lazily, with
itertools.repeat
, like this>>> from itertools import chain, repeat >>> chain.from_iterable((repeat(item, count) for item, count in zip(x,y))) <itertools.chain object at 0x7fabe40b5320> >>> list(chain.from_iterable((repeat(item, cnt) for item, cnt in zip(x,y)))) [2, 3, 3, 4, 4, 4]
Please note that the
chain
returns an iterable, not a list. So, if you don't want all the elements at once, you can get the items one by one from it. This will be highly memory efficient if thecount
is going to be a very big number, as we don't create the entire list in the memory immediately. We generate the values on-demand. -
Thanks ShadowRanger. You can actually apply
repeat
overx
andy
and get the result like this>>> list(chain.from_iterable(map(repeat, x, y))) [2, 3, 3, 4, 4, 4]
here,
map
function will apply the values fromx
andy
torepeat
one by one. So, the result ofmap
will be>>> list(map(repeat, x, y)) [repeat(2, 1), repeat(3, 2), repeat(4, 3)]
Now, we use
chain.from_iterable
to consume values from each and every iterable from the iterable returned bymap
.