1

I have an array with coins, e.g. (coins=[10, 50, 100]) and an array of the quantities of each coin (e.g. quantity=[1, 2, 1]). I want to generate a new list l, which shows all coins I have (e.g l=[10, 50, 50, 100]).

So far i have this, which does the trick:

coins=[i for s in [b*[a] for a,b in zip(coins,quantity)] for i in s]

Is there a better way to solve this in python, than to create a list of lists and then flatten it?

jan-seins
  • 1,253
  • 1
  • 18
  • 31

4 Answers4

4

You can leverage itertools chain and repeat:

from itertools import repeat,chain

coins=[10, 50, 100]
quantity=[1, 2, 1]

result = list(chain.from_iterable(map(repeat, coins, quantity))) # thx @ miradulo

print(result)

Output:

[10, 50, 50, 100]

Advantage: it does not build interal lists that then get flattened but generates the values as iterables.

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • 1
    This implementation is actually similar to my suggestion of calling `Counter.elements()` https://github.com/python/cpython/blob/018e1b7aad8d1a33ee14aae5c466d581d31e2369/Lib/collections/__init__.py#L596 – Chris_Rands Mar 16 '18 at 10:12
2

Assuming the final order is not important, you could use a collections.Counter():

>>> from collections import Counter
>>> c = Counter(dict(zip(coins, quantity)))
>>> list(c.elements())
[10, 100, 50, 50]
>>> c
Counter({50: 2, 10: 1, 100: 1})
Chris_Rands
  • 38,994
  • 14
  • 83
  • 119
1

You could use sum to add the lists together:

L = sum(([c] * q for c, q in zip(coins, quantity)), [])

numpy also has a function that does exactly what you need:

numpy.repeat(coins, quantity)

EDIT: as @Chris_Rands points out sum is not optimal for long lists of lists. It seems to be the fastest solution for quantity=[100, 200, 100] but for quantity=[1000, 2000, 1000] numpy is much faster. Both are faster than the OP solution.

Stuart
  • 9,597
  • 1
  • 21
  • 30
  • 1
    You could, but you should not https://stackoverflow.com/questions/952914/making-a-flat-list-out-of-list-of-lists-in-python – Chris_Rands Mar 15 '18 at 19:04
0

what i can figure out is :

for i in range(len(quantity)):
    for j in range(quantity[i]):
        print(coins[i])
prabhat mishra
  • 202
  • 2
  • 14