8

以下是一些关于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]  

我的问题是

  1. tee 是如何工作的,为什么有时原始迭代器“有数据”而其他时候没有?
  2. 我可以将迭代深度副本保留为“状态种子”以保持原始迭代器状态并将其用于以后使用吗?
  3. 我可以交换 2 个 iters 或 2 个itertools.tee吗?

谢谢!

4

1 回答 1

15

tee接管原来的迭代器;一旦你 tee 一个迭代器,丢弃原来的迭代器,因为 tee 拥有它(除非你真的知道你在做什么)。

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

import copy, itertools
it = [1,2,3,4]
a, b = itertools.tee(it)
c = copy.copy(a)

...或通过调用a.__copy__().

请注意,它tee通过跟踪从原始迭代器中消耗的所有迭代值来工作,这些迭代器可能仍被副本消耗。

例如,

a = [1,2,3,4]
b, c = itertools.tee(a)
next(b)

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

这样做的结果是您需要通过复制 tee 来小心“保存状态”。如果您实际上没有使用“已保存状态” tee 中的任何值,您将导致 tee 将迭代器返回的每个值永久保存在内存中(直到复制的 tee 被丢弃并收集)。

于 2010-10-18T08:04:53.040 回答