-1

I have two lists:

x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
y=  [5, 2, 3, 2, 3, 3, 3, 3, 5, 3]

I want to create a new list that contains of multiplies x's first element with the amount of y's first element. That is, I'm looking to produce:

z = [0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, ...]

How can I create this list?

BrokenBenchmark
  • 18,126
  • 7
  • 21
  • 33

4 Answers4

1

You can use itertools.chain.from_iterable() and itertools.repeat():

list(chain.from_iterable(repeat(elem, count) for elem, count in zip(x, y)))

This outputs:

[0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9]
BrokenBenchmark
  • 18,126
  • 7
  • 21
  • 33
  • 3
    Even shorter, use `map` (which basically acts as a zipWith-type function when you give it more than one iterable) : `list(chain.from_iterable(map(repeat, x, y)))` – chepner Apr 28 '22 at 01:07
1

One easy way is to use a nested list comprehension with zip:

xs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
ys = [5, 2, 3, 2, 3, 3, 3, 3, 5, 3]

output = [x for x, y in zip(xs, ys) for _ in range(y)]
print(output)
# [0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9]
j1-lee
  • 13,764
  • 3
  • 14
  • 26
0

You can:

  • Use a list comprehension to create a list of lists of repeated values
  • Use * to unpack the list of lists into iterable arguments (each argument is one of the lists) for itertools.chain() to treat as a single sequence
x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
y = [5, 2, 3, 2, 3, 3, 3, 3, 5, 3]

import itertools
z = list(itertools.chain(*[[x[i]] * y[i] for i in range(len(x))]))
print(z)

Output:

[0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9]

As highlighted by @chepner in a comment, the argument unpacking step using * can be avoided by using chain.from_iterable() instead of chain():

z = list(itertools.chain.from_iterable([[x[i]] * y[i] for i in range(len(x))]))
constantstranger
  • 9,176
  • 2
  • 5
  • 19
-1

Without extra imports you can use sum( , []) to "flat" the list. It is not recommended but it works. The best way to concatenate lists, as suggested by the doc, is to use itertools.chain

x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
y=  [5, 2, 3, 2, 3, 3, 3, 3, 5, 3]

sum([[x_]*y_ for x_, y_ in zip(x, y)], [])

Since performance should not be underestimated and imports optimize:

import itertools as it

flat = it.chain.from_iterable(it.starmap(it.repeat, zip(x, y)))

print(list(flat))

Reference to sum solution: see answer of Kenan Banks. If you care only on syntax (monoids) and not on efficiency

cards
  • 3,936
  • 1
  • 7
  • 25
  • 1
    If you hate imports, you can just use a nested loop in the comprehension, per [j1-lee's answer](https://stackoverflow.com/a/72036802/364696). Using `sum` is a *terrible* idea, not just because it's not the intended purpose of `sum`, but because it's a Schlemiel the Painter's Algorithm, taking `O(n²)` work, vs. `O(n)` for sane concatenation strategies. – ShadowRanger Apr 30 '22 at 18:44
  • @ShadowRanger Yes, but it still works. Your comment, together with the link to the doc, is contained in my answer. Again, the doc does not recommend to use it but it is still _syntactically correct_. Finally, the suggestion to use `chain` is mentioned. Nothing against imports... but smt to check some stuffs on the fly can be still useful – cards Apr 30 '22 at 18:52