繁体   English   中英

基于另一个列表中的元素重复一个列表中的元素

[英]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次。

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)从两个列表中创建一个 2 元组列表,将每个元素与另一个列表中的相应元素配对。 这为您提供了在您的用例中需要传递给itertools.repeat
  • itertools.chain - 将生成的迭代器列表扁平化为单个值列表。 你可以像我一样chain(*iterable)或者像 Martijn Peters 那样chain.from_iterable(iterable)

zip()函数itertools.repeat()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 向前兼容的导入)。

演示:

>>> 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)]

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

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

使用列表理解,您想要获得的是:

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

对于短列表,使用sum(list, [])可以方便地实现

内置函数 sum 对 sum(list, []) 有什么作用?

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM