如何创建python迭代器的副本?

Har*_*GUL 17 python iterator python-2.7 python-3.x

在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
Run Code Online (Sandbox Code Playgroud)

正如您在示例中看到的,first_it和second_it都引用相同的迭代器对象.是否可以创建一个不引用原始对象的迭代器对象的副本?

注意 此问题是关于如何按值创建迭代器对象的副本.所以不要提及for item in my_list:类似的解决方案.
提前致谢

Mar*_*ers 26

使用该itertools.tee()功能制作副本; 这些使用缓冲区在不同的迭代器之间共享结果:

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
Run Code Online (Sandbox Code Playgroud)

请注意,您不应再使用原始迭代器; 只使用发球台.

请注意,缓冲区还意味着如果您将其中一个副本推进到其他副本之前,这些可能会产生巨大的内存成本!从文档:

这个itertool可能需要大量的辅助存储(取决于需要存储多少临时数据).一般来说,如果一个迭代器使用了大部分或全部数据的另一迭代开始前,它是更快地使用list()替代tee().

  • @ Jean-FrançoisFabre:这对发电机不起作用.尝试使用`while True:生成random.random()`的生成器. (4认同)
  • 我试过`copy.copy()`它也有效.也许有一个隐藏的捕获? (2认同)
  • @Jean-FrançoisFabre:仅仅因为某些迭代器对象是可复制的,并不意味着它们都是可复制的。该示例生成一个“ list_iterator()”对象,该对象仅需要存储对原始列表对象和当前位置的引用。这很容易复制。但是对于一个无限的随机生成器,没有“当前位置”,只有某些东西接下来可能会产生另一个值。 (2认同)