[英]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, [])
可以方便地实现
因为对于短列表,它可能比itertools.chain
+ itertools.repeat
更快(也更直接)。
sum([ [a_i]*b_i for a_i, b_i in zip(a, b) ], [])
对于长列表,坚持使用itertools.chain
和itertools.repeat
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.