根据另一个列表中的元素重复一个列表中的元素

Repeat elements in one list based on elements from another

给定以下列表:

a = [0, 5, 1]
b = [1, 2, 1]

我想通过 [b] 中相应位置的编号重复 [a] 中的每个元素以生成此内容:

[0, 5, 5, 1]

即0出现1次,5出现2次,1出现1次。

使用zip() function with itertools.repeat() and itertools.chain.from_iterable():

try:
    # use iterator zip on Python 2 too
    from future_builtins import zip
except ImportError:
    pass
from itertools import repeat, chain

list(chain.from_iterable(repeat(value, count) for value, count in zip(a, b)))

(我为那些还不能切换到 Python 3 的人添加了 Python 2 forward-compatible import)。

演示:

>>> from itertools import repeat, chain
>>> a = [0, 5, 1]
>>> b = [1, 2, 1]
>>> list(chain.from_iterable(repeat(value, count) for value, count in zip(a, b)))
[0, 5, 5, 1]

另一种方法是使用列表理解;这比较慢,因为重复元素是在字节码而不是 C:

中完成的
[value for value, count in zip(a, b) for _ in range(count)]
In [7]: a = [0, 5, 1]

In [8]: b = [1, 2, 1]

In [9]: list(itertools.chain(*(itertools.repeat(elem, n) for elem, n in zip(a, b))))
Out[9]: [0, 5, 5, 1]

In [10]: b = [2, 3, 4]

In [11]: list(itertools.chain(*(itertools.repeat(elem, n) for elem, n in zip(a, b))))
Out[11]: [0, 0, 5, 5, 5, 1, 1, 1, 1]

这里的棋子如下:

  • itertools.repeat(elem, n) - 重复 elem n 次
  • zip(a, b) 从两个列表中创建一个二元组列表,将每个元素与另一个列表中的相应元素配对。这为您提供了在您的用例中需要传递给 itertools.repeat 的确切内容。
  • itertools.chain - 将生成的迭代器列表展平为单个值列表。您可以像我所做的那样 chain(*iterable) 或像 Martijn Peters 那样 chain.from_iterable(iterable)

这可以使用 enumerate() 直接完成:

a = [0, 5, 1]
b = [1, 2, 1]
[ele for i, ele in enumerate(a) for j in range(b[i])]

使用list comprehension,你想要得到的是:

[a[0]]*b[0] + [a[1]]*b[1] + [a[2]]*b[2]

对于短列表,使用 sum(list, [])

可以很方便地实现

因为对于简短列表,它可能比 itertools.chain + itertools.repeat 更快(也更直接)。

sum([ [a_i]*b_i for a_i, b_i in zip(a, b) ], [])

对于长列表,坚持使用 itertools.chainitertools.repeat