I have two lists, x
and y
:
>>> x = [2, 3, 4]
>>> y = [1, 2, 3]
I want to use these to create a
One way to achieve this is via using .elements() function of collections.Counter() along with zip. For example:
>>> from collections import Counter
>>> x = [2, 3, 4]
>>> y = [1, 2, 3]
# `.elements()` returns an object of `itertool.chain` type, which is an iterator.
# in order to display it's content, here type-casting it to `list`
>>> list(Counter(dict(zip(x,y))).elements())
[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
the x
and y
so that the element from x
and its corresponding count from y
are grouped as a single tuple. Then, we iterate count
number of items to produce the same item.
If your objects in x
are immutables, then you can create count
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 the count
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
over x
and y
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 from x
and y
to repeat
one by one. So, the result of map
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 by map
.
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])
Simple using for
loop.
>>> x = [2, 3, 4]
>>> y = [1, 2, 3]
>>> final = []
>>> for index, item in enumerate(y):
final.extend([x[index]]*item)