2017-02-09 59 views
6

在python中,我尝试使用赋值创建迭代器的副本,但是它创建了引用原始迭代器本身的迭代器的副本。例如:如何创建python迭代器的副本?

my_list = [5, 4, 3,2] 
first_it = iter(my_list) 
second_it = first_it 
print next(first_it)  #it will print 5 
print next(second_it)  #it will print 4 
print next(first_it)  #it will print 3 

正如您在示例中看到的,first_it和second_it都指向相同的迭代器对象。是否有可能创建一个不参考原始对象的迭代器对象的副本?

注意 这个问题是关于如何通过值创建迭代器对象的副本。所以不要提for item in my_list:之类的解决方案。
在此先感谢

回答

9

使用itertools.tee() function生成副本;这些使用缓冲区进行不同的迭代器之间共享的结果:

from itertools import tee 

my_list = [5, 4, 3,2] 
first_it = iter(my_list) 
first_it, second_it = tee(first_it) 
print next(first_it) # prints 5 
print next(second_it) # prints 5 
print next(first_it) # prints 4 

请注意,您不应该再使用原来的迭代器;只使用T恤。

请注意,缓冲区也意味着,如果您将其中一个副本提前超过其他副本,这些副本可能会产生大量内存成本!从文档:

这itertool可能需要大量的辅助存储(取决于需要存储多少临时数据)。通常,如果一个迭代器在另一个迭代器启动之前使用大部分或全部数据,则使用list()而不是tee()会更快。

+0

我用'copy.copy()'试过了,它也起作用了。也许有一个隐藏的捕获? –

+2

@ Jean-FrançoisFabre:这不适用于发电机。例如,尝试使用'while True:yield random.random()'的生成器。可能与 –

+0

有关:“你不能腌制发生器”。 –