创建列表元素的多个副本

时间:2014-10-29 11:59:49

标签: python

我有一系列元素,每个元素都与元组中的权重w(正整数)相关联。有什么好的方法(最好是基于迭代器的)来创建包含每个元素w_i的{​​{1}}个实例的序列或列表?

e_i

3 个答案:

答案 0 :(得分:2)

使用带有嵌套循环的列表推导:

unrolled = [c for c, count in weighted for _ in range(count)]

如果您使用的是Python 2,则可以使用xrange()代替。

如果您喜欢itertools,可以使用itertools.chain.from_iterable()将其变为惰性迭代:

from itertools import chain

chain.from_iterable([c] * count for c, count in weighted)

演示:

>>> weighted = [ ("a", 3), ("b", 1), ("c", 4) ]
>>> [c for c, count in weighted for _ in range(count)]
['a', 'a', 'a', 'b', 'c', 'c', 'c', 'c']
>>> from itertools import chain
>>> list(chain.from_iterable([c] * count for c, count in weighted))
['a', 'a', 'a', 'b', 'c', 'c', 'c', 'c']

我使用list()chain迭代器重新转换为序列。

答案 1 :(得分:1)

Counter内置了这个逻辑,假设顺序并不重要

>>> weighted = [ ("a", 3), ("b", 1), ("c", 4) ]
>>> from collections import Counter
>>> c = Counter(dict(weighted))
>>> list(c.elements())
['a', 'a', 'a', 'c', 'c', 'c', 'c', 'b']

使用itertools(很多)的另一种方式

>>> from itertools import chain, repeat, starmap
>>> list(chain.from_iterable(starmap(repeat, weighted)))
['a', 'a', 'a', 'b', 'c', 'c', 'c', 'c']

答案 2 :(得分:0)

此方法基本上使用生成器表达式和join创建单个字符串,然后将该字符串转换为list

weighted = [ ("a", 3), ("b", 1), ("c", 4) ]
unrolled = list(''.join([letter*count for letter,count in weighted]))

>>> unrolled
['a', 'a', 'a', 'b', 'c', 'c', 'c', 'c']