Python 使用itertools.tee覆盖迭代器
我希望在函数内部使用Python 使用itertools.tee覆盖迭代器,python,itertools,Python,Itertools,我希望在函数内部使用itertools.tee,将原始迭代器作为参数,但我担心退出函数时可能会重用旧迭代器,而使用tee时不应该这样做 如果我在与迭代器相同的块中调用tee,那么它似乎是安全的: my_iter = create_some_iterator() my_iter, my_lookahead = itertools.tee(my_iter) 因为my_iter指向的原始迭代器(我假设)没有更多的引用计数,my_iter现在指向它的副本,所以无法使用原始迭代器 但如果我通过一个函数
itertools.tee
,将原始迭代器作为参数,但我担心退出函数时可能会重用旧迭代器,而使用tee
时不应该这样做
如果我在与迭代器相同的块中调用tee,那么它似乎是安全的:
my_iter = create_some_iterator()
my_iter, my_lookahead = itertools.tee(my_iter)
因为my_iter
指向的原始迭代器(我假设)没有更多的引用计数,my_iter
现在指向它的副本,所以无法使用原始迭代器
但如果我通过一个函数传递它,这仍然是真的吗
def foo(some_iter):
some_iter, some_lookahead = itertools.tee(some_iter)
# Do some lookahead tasks
my_iter = create_some_iterator()
foo(my_iter)
next(my_iter) # Which iter is this?
退出功能后,my\u iter
是否指向my\u iter
的副本?或者它仍然指向我不应该使用的原始迭代器
我很担心,因为大多数时候这不是一个问题,但有时我会被这一点所困扰,特别是在像PyPy这样不太常见的实现中
这就是上面示例中
id
告诉我的,这表明我不能以这种方式使用迭代器,但我也可能误解了id
在这里的含义:
import itertools
def foo(some_iter):
print(' some_iter id:', id(some_iter))
some_iter, some_lookahead = itertools.tee(some_iter)
print(' new some_iter id:', id(some_iter))
print(' some_lookahead id:', id(some_lookahead))
# Do some lookahead tasks
my_iter = iter(range(10))
print('my_iter id:', id(my_iter))
foo(my_iter)
print('my_iter id after foo:', id(my_iter))
输出:
my_iter id: 139686651427120
some_iter id: 139686651427120
new some_iter id: 139686650411776
some_lookahead id: 139686650411712
my_iter id after foo: 139686651427120
my\u iter
仍保留其原始的id
,而不是tee
分配给某些iter
的id
更新:对不起,这不是我想问的问题。在第二部分,我自己或多或少地回答了这个问题 我更想问的是,为什么它仍然像预期的那样工作,副本中的迭代会反映在原始版本中,即使它们有不同的ID 也有一半人试图问如何处理这个问题,但提供了一个解决方案 我试图缩小这个问题,但缩小得太多了 我试图结束这个问题,但它不会让我了,所以不知道如何处理这个问题。向已经回答的人道歉 离开函数后,我的iter是否指向我的iter副本?或者它仍然指向我不应该使用的原始迭代器 它仍然指向原文。Python是一种“按值传递”的语言(尽管它的所有值都是引用,所以有时有点混乱)。它不是一种通过引用传递的语言,对参数的赋值对于函数来说是完全本地的,对调用者来说是不可见的 离开函数后,我的iter是否指向我的iter副本?或者它仍然指向我不应该使用的原始迭代器
它仍然指向原文。Python是一种“按值传递”的语言(尽管它的所有值都是引用,所以有时有点混乱)。它不是一种通过引用传递的语言,对参数的赋值对于函数来说是完全本地的,对调用者来说是不可见的。在Python中,向函数传递内容永远不会产生副本
def标识(x):
返回x
iter1=iter(范围(10))
iter2=标识(iter1)
断言iter1是iter2#断言“对象相等”
Python函数总是这样工作的
itertools.tee的行为与此无关。我们专门处理迭代器的事实与此无关
itertools.tee
返回副本的事实是itertools.tee
特有的行为
如果您有一些空闲时间,这个演讲会非常有启发性:在Python中,将某些内容传递给函数永远不会产生副本
def标识(x):
返回x
iter1=iter(范围(10))
iter2=标识(iter1)
断言iter1是iter2#断言“对象相等”
Python函数总是这样工作的
itertools.tee的行为与此无关。我们专门处理迭代器的事实与此无关
itertools.tee
返回副本的事实是itertools.tee
特有的行为
如果你有空闲时间,这个演讲会很有启发性: