itertools.tee如何工作,可以复制'itertools.tee'来复制以保存它的"状态"?

use*_*514 6 python iterator duplicates tee

以下是一些测试itertools.tee:

    li = [x for x in range(10)]
    ite = iter(li)
==================================================
    it = itertools.tee(ite, 5)
    >>> type(ite)
    <type 'listiterator'>
    >>> type(it)
    <type 'tuple'>
    >>> type(it[0])
    <type 'itertools.tee'>
    >>> 

    >>> list(ite)
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> list(it[0])          # here I got nothing after 'list(ite)', why?
    []
    >>> list(it[1])
    []
====================play again===================
    >>> ite = iter(li)
    it = itertools.tee(ite, 5)
    >>> list(it[1])
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> list(it[2])
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> list(it[3])
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> list(it[4])
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> list(ite)
    []                       # why I got nothing? and why below line still have the data?   
    >>> list(it[0])
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> list(it[0])
    []
====================play again===================    
    >>> ite = iter(li)
    itt = itertools.tee(it[0], 5)    # tee the iter's tee[0].
    >>> list(itt[0])
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> list(itt[1])
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> list(it[0])
    []                               # why this has no data?
    >>> list(it[1])
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> list(ite)
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]  
Run Code Online (Sandbox Code Playgroud)

我的问题是

  1. 如何开展工作以及为什么有时原始的'有数据'而其他时间却没有?
  2. 我可以保留一个深层副本作为"状态种子"来保持原始迭代器状态并开发它以便以后使用吗?
  3. 我可以换掉2个或2个itertools.tee吗?

谢谢!

Gle*_*ard 12

tee接管原始迭代器; 一旦你开发了一个迭代器,就丢弃原来的迭代器,因为发球台拥有它(除非你真的知道你在做什么).

您可以使用该copy模块制作三通的副本:

import copy, itertools
it = [1,2,3,4]
a, b = itertools.tee(it)
c = copy.copy(a)
Run Code Online (Sandbox Code Playgroud)

......或通过电话a.__copy__().

请注意,tee通过跟踪从原始迭代器消耗的所有迭代值(仍可能由副本使用)来工作.

例如,

a = [1,2,3,4]
b, c = itertools.tee(a)
next(b)
Run Code Online (Sandbox Code Playgroud)

此时,tee对象底层b并且c已经读取了一个值,1.它将它存储在内存中,因为它必须在c迭代时记住它.它必须保留内存中的每个值,直到它被发球台的所有副本消耗.

这样做的结果是你需要通过复制T恤来小心"保存状态".如果您实际上没有使用"已保存状态"T恤中的任何值,那么您将使tee 永久地将迭代器返回的每个值保留在内存中(直到复制的T形管被丢弃和收集).

  • 不,通常无法复制迭代器。迭代器*可以*像`tee`实例那样暴露`__copy__`,但通常不会。 (2认同)