我想通过迭代器重复遍历列表(N次),以便不在列表中实际存储N个副本。没有编写我自己的生成器,有内置或优雅的方法吗?
理想情况下,itertools.cycle(my_list)会有第二个参数来限制它循环的次数...唉,没有这样的运气。
答案 0 :(得分:15)
import itertools
itertools.chain.from_iterable(itertools.repeat([1, 2, 3], 5))
Itertools是一个很棒的图书馆。 :)
答案 1 :(得分:8)
itertools.chain.from_iterable(iter(L) for x in range(N))
答案 2 :(得分:6)
对于需要多次遍历列表的特殊情况,这不是太糟糕。
确实会创建一个n
my_list
引用列表,所以如果n
非常大,最好使用Darthfelt的答案
>>> import itertools as it
>>> it.chain(*[my_list]*n)
答案 3 :(得分:6)
所有其他答案都非常好。另一种解决方案是使用islice
。这允许您在任何时候中断循环:
>>> from itertools import islice, cycle
>>> l = [1, 2, 3]
>>> list(islice(cycle(l), len(l) * 3))
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> list(islice(cycle(l), 7))
[1, 2, 3, 1, 2, 3, 1]
答案 4 :(得分:4)
你说你不想编写自己的生成器,但生成器表达式可能是完成你所追求的最简单,最有效的方法。它不需要任何函数调用或任何模块的导入。 itertools
是一个很棒的模块,但在这种情况下可能没有必要吗?
some_list = [1, 2, 3]
cycles = 3
gen_expr = (elem for _ in xrange(cycles) for elem in some_list)
或只是
(elem for _ in xrange(3) for elem in [1, 2, 3])
或
for elem in (e for _ in xrange(3) for e in [1, 2, 3]):
print "hoo-ray, {}!".format(elem)
答案 5 :(得分:2)
@ Darthfett的回答记录为itertools recipes:
from itertools import chain, repeat
def ncycles(iterable, n):
"Returns the sequence elements n times"
return chain.from_iterable(repeat(tuple(iterable), n))
list(ncycles(["a", "b"], 3))
# ['a', 'b', 'a', 'b', 'a', 'b']
为方便起见,我补充说more_itertools
库为您实现了这个配方(和许多其他配方):
import more_itertools as mit
list(mit.ncycles(["a", "b"], 3))
# ['a', 'b', 'a', 'b', 'a', 'b']