在Python中复制迭代器

skr*_*320 5 python iterator copy

制作迭代器的(浅)副本时,它将返回一个新的迭代器。

from copy import copy


data = [1, 2, 3, 4]

iter1 = iter(data)
iter2 = copy(iter1)

[i for i in iter1]    #[1, 2, 3, 4]
[i for i in iter2]    #[1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

当对使用itertools创建的迭代器进行浅表复制时,它会返回相同的迭代器,而deepcopy将返回新的迭代器。

from copy import copy, deepcopy
from itertools import takewhile


data = [1, 2, 3, 4]

iter1 = takewhile(lambda x: x < 5, data)
iter2 = copy(iter1)
iter3 = deepcopy(iter1)

[i for i in iter1]    #[1, 2, 3, 4]
[i for i in iter2]    #[] because it's the same iterator
[i for i in iter3]    #[1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

这是预期的行为吗?我在文档的任何地方都找不到关于复制迭代器的任何信息。我知道有一个itertools.tee()函数,但是它的可用性受到限制(例如,当我们遍历一个变化的集合时)。

Jos*_*Fox 2

这是已知的行为。迭代器是有状态的:当前位置就是状态。因此,浅层副本共享该状态是有道理的,如您所展示的示例所示。

“可复制迭代器”的规范实际上早在 2003 年就以 PEP 方式进行了讨论。

他们指出,“copy.copy在用户编码的迭代器类型中对[单独迭代]的‘支持’几乎总是‘偶然的’......仅当“存在某些条件时,副本才可以相对于原始版本独立迭代”在实施中。

他们决定采用该 PEP。