Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 是否有一种优雅的方法通过迭代在列表中循环N次(如itertools.cycle,但限制循环)?_Python_Iterator - Fatal编程技术网

Python 是否有一种优雅的方法通过迭代在列表中循环N次(如itertools.cycle,但限制循环)?

Python 是否有一种优雅的方法通过迭代在列表中循环N次(如itertools.cycle,但限制循环)?,python,iterator,Python,Iterator,我希望通过迭代器重复(N次)遍历一个列表,这样就不会在内存中实际存储列表的N个副本。有没有一种内置的或优雅的方法可以在不编写自己的生成器的情况下实现这一点 理想情况下,itertools.cycle(我的清单)将有第二个参数来限制它的循环次数。。。唉,没有这样的运气 itertools.chain.from_iterable(iter(L) for x in range(N)) Itertools是一个很棒的图书馆。:) 对于需要对列表进行多次迭代的特殊情况,这并不太糟糕 它确实创建了一个n对

我希望通过迭代器重复(N次)遍历一个列表,这样就不会在内存中实际存储列表的N个副本。有没有一种内置的或优雅的方法可以在不编写自己的生成器的情况下实现这一点

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

itertools.chain.from_iterable(iter(L) for x in range(N))

Itertools是一个很棒的图书馆。:)

对于需要对列表进行多次迭代的特殊情况,这并不太糟糕

它确实创建了一个
n
my_list
的引用列表,因此如果
n
非常大,最好使用Darthfelt的答案

>>> import itertools as it
>>> it.chain(*[my_list]*n)

其他答案都很好。另一个解决方案是使用
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]

您说过您不想编写自己的生成器,但是生成器表达式可能是实现您所追求的目标的最简单、最有效的方法。它不需要任何函数调用或导入任何模块
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])


@Darthfett的答案记录为:

为了方便起见,我补充说,库为您实现了这个配方(以及许多其他配方):


我相信把一个列表乘以一个整数是不够好的,对吗<代码>[1,2,3]*4@C2H5OH将创建列表的4个浅拷贝(不需要N个拷贝)。@Darthfett:的确如此。这就是为什么它是一个评论。但您会同意这是最优雅的解决方案:-PNice,我不知道islice使用的
stop
值大于iterable的长度。@Darthfett,是的,是这样的。但这与此无关;循环返回的iterable无限长。我非常喜欢这些生成器表达式。它们比我意识到的更紧凑。我将把答案归功于@Darthfett,因为从技术上讲,我要求的是非自滚发电机,但如果我能接受两个,我也会接受你的(可能还有其他人的):-)谢谢!这是一个相当清楚的答案,不涉及我自己的生成器/迭代器(尽管Matt Anderson的答案表明这也不太混乱),并且是满足我问题的第一个答案之一。所以,我接受了。谢谢我试图避免在内存中复制列表(或对它的引用),否则只要:mylist*n就足够了。:-)不过,谢谢你的意见。需要明确的是,通过*list操作符扩展列表和乘以n与仅仅将列表乘以n有什么区别吗?@JJC,
mylist*n
创建一个包含
len(mylist)*n)
元素的列表。对于这个答案,您只需创建一个
n
元素列表,因此根据
len(mylist)
n
这可能会产生巨大的差异。我知道[1,2,3,4]*2将创建一个包含8个元素的列表。你是说*1,2,3,4]*2只创建了两个元素?对不起,我弄糊涂了。谢谢。@JJC,no[[1,2,3,4]]*2创建了一个包含两个元素的hank的列表,但这与Darthfett接受的答案相同。是的,它们是等价的。我进行了编辑,以澄清他的代码是现有的
itertools
recipe(不早于Python 2.3)。我发布此选项是为了演示一个实现这些配方的第三方库,如果需要,可以避免手动实现。谢谢,很好。这个“更多工具”软件包看起来非常方便。谢谢分享。
(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)
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']
import more_itertools as mit

list(mit.ncycles(["a", "b"], 3))
# ['a', 'b', 'a', 'b', 'a', 'b']