给定以下列表:
a = [0, 5, 1]
b = [1, 2, 1]
我想通过[b]中每个相应位置的数字来重复[a]中的每个元素,得到以下结果:
[0, 5, 5, 1]
即0出现1次,5出现2次,1出现1次。
给定以下列表:
a = [0, 5, 1]
b = [1, 2, 1]
[0, 5, 5, 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)
- 将两个列表中的每个元素一一对应,形成一个由二元组组成的列表。这正好是你在使用中需要传递给 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)))
演示:
>>> 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
。