是否有一种优雅的方式通过迭代循环遍历列表N次(如itertools.cycle但限制循环)?

时间:2012-04-26 00:02:12

标签: python iterator

我想通过迭代器重复遍历列表(N次),以便不在列表中实际存储N个副本。没有编写我自己的生成器,有内置或优雅的方法吗?

理想情况下,itertools.cycle(my_list)会有第二个参数来限制它循环的次数...唉,没有这样的运气。

6 个答案:

答案 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']