Python itertools、克隆和缓存

Python itertools、克隆和缓存,python,itertools,Python,Itertools,假设:当使用python itertools.tee时,所有重复的迭代器都引用原始迭代器,并且缓存原始迭代器以提高性能 在下面的查询中,我主要关心的是我对预期/正确缓存行为的看法。 编辑:我认为适当的缓存是基于有缺陷的功能假设。最终需要在tee周围使用一个小包装器,这可能会对缓存产生影响 问题: 假设我使用tee创建了3个迭代器克隆:a,b,c=itertools.teemyiter,3。同时假设,在这一点上,我删除了对原始的所有引用,myiter的意思是,我的代码没有很好的方法可以在以后引用原

假设:当使用python itertools.tee时,所有重复的迭代器都引用原始迭代器,并且缓存原始迭代器以提高性能

在下面的查询中,我主要关心的是我对预期/正确缓存行为的看法。 编辑:我认为适当的缓存是基于有缺陷的功能假设。最终需要在tee周围使用一个小包装器,这可能会对缓存产生影响

问题: 假设我使用tee创建了3个迭代器克隆:a,b,c=itertools.teemyiter,3。同时假设,在这一点上,我删除了对原始的所有引用,myiter的意思是,我的代码没有很好的方法可以在以后引用原始代码

在以后的代码中,如果我决定要另一个myiter的克隆,我可以重新测试我的一个副本吗?使用正确的缓存返回到最初缓存的myiter

换言之,在后来的某个时候,我希望我能用这个: a、 b,c,d=itertools.teemyiter,4。 但是,由于我已经放弃了对原始myiter的所有引用,因此我所能收集到的最好信息是: copytee=itertools.teea,其中“a”来自前一个tee


tee知道我想要什么吗?我真的想在原始myiter的基础上创建一个克隆,而不是一个可能被部分消耗的中间克隆

tee没有什么神奇之处。这很聪明;-在任何时候,tee都会克隆传递给它的迭代器。这意味着克隆的迭代器将从现在开始生成传入迭代器生成的值。但它们不可能重现调用tee之前生成的值

让我们用比你的例子简单得多的东西来展示它:

>>> it = iter(range(5))
>>> next(it)
0
0现在已经不存在了——永远。tee拿不回来了:

>>> a, b = tee(it)
>>> next(a)
1
所以a推动它产生下一个价值。缓存的就是这个值,这样其他克隆也可以复制它:

>>> next(b)
1
为了得到这个结果,它没有被触碰——从内部缓存中检索到了1。现在所有这些,a和b都产生了1,1也永远消失了

我不知道这是否回答了你的问题-tee知道我想要什么吗?似乎需要心灵感应;-也就是说,我不知道你所说的适当缓存是什么意思。如果您给出一个您希望的输入/输出行为的确切示例,这将非常有帮助

除此之外,Python文档给出了与tee等效的Python代码,也许研究一下这一点可以回答您的问题:

def tee(iterable, n=2):
    it = iter(iterable)
    deques = [collections.deque() for i in range(n)]
    def gen(mydeque):
        while True:
            if not mydeque:             # when the local deque is empty
                newval = next(it)       # fetch a new value and
                for d in deques:        # load it to all the deques
                    d.append(newval)
            yield mydeque.popleft()
    return tuple(gen(d) for d in deques)

例如,您可以从中看到,没有缓存任何关于迭代器内部状态的内容—缓存的只是从调用tee开始,传入迭代器生成的值。每个克隆都有自己的dequefifo列表,其中列出了到目前为止生成的传入迭代器的值,这是所有克隆都知道的有关传入迭代器的信息。所以,对于你真正想要的东西来说,这可能太简单了。

T恤并没有什么神奇之处。这很聪明;-在任何时候,tee都会克隆传递给它的迭代器。这意味着克隆的迭代器将从现在开始生成传入迭代器生成的值。但它们不可能重现调用tee之前生成的值

让我们用比你的例子简单得多的东西来展示它:

>>> it = iter(range(5))
>>> next(it)
0
0现在已经不存在了——永远。tee拿不回来了:

>>> a, b = tee(it)
>>> next(a)
1
所以a推动它产生下一个价值。缓存的就是这个值,这样其他克隆也可以复制它:

>>> next(b)
1
为了得到这个结果,它没有被触碰——从内部缓存中检索到了1。现在所有这些,a和b都产生了1,1也永远消失了

我不知道这是否回答了你的问题-tee知道我想要什么吗?似乎需要心灵感应;-也就是说,我不知道你所说的适当缓存是什么意思。如果您给出一个您希望的输入/输出行为的确切示例,这将非常有帮助

除此之外,Python文档给出了与tee等效的Python代码,也许研究一下这一点可以回答您的问题:

def tee(iterable, n=2):
    it = iter(iterable)
    deques = [collections.deque() for i in range(n)]
    def gen(mydeque):
        while True:
            if not mydeque:             # when the local deque is empty
                newval = next(it)       # fetch a new value and
                for d in deques:        # load it to all the deques
                    d.append(newval)
            yield mydeque.popleft()
    return tuple(gen(d) for d in deques)

例如,您可以从中看到,没有缓存任何关于迭代器内部状态的内容—缓存的只是从调用tee开始,传入迭代器生成的值。每个克隆都有自己的dequefifo列表,其中列出了到目前为止生成的传入迭代器的值,这是所有克隆都知道的有关传入迭代器的信息。所以对于你真正希望的东西来说,这可能太简单了。

你试过这样做吗?如果它不起作用,请给出错误消息以及遇到的行为。我的迭代器工作正常,但我无法确认缓存是否会转移到二手克隆。我计划在一个巨大的迭代器上使用它,并希望确保我做得正确。你试过这样做吗?如果它不起作用,请给出错误消息以及遇到的行为。我的迭代器是funct
正在正常运行,但我无法确认缓存是否已转移到二手克隆。我计划在一个巨大的迭代器上使用它,并希望确保我做得正确。一个二手克隆人对原始迭代器一无所知。它将只生成第一手迭代器生成的值-&您不能再次使用第一手迭代器!就像你不应该在制作第一手teeit克隆后再次使用它一样。不管怎样,国际热核聚变实验堆也没有原始的德克——每个克隆体都有一个德克,彼此独立。很抱歉,但我仍然不清楚正确缓存对您意味着什么。给出一个准确的期望输入/输出示例,或就此放弃-你的最后一个例子很好地说明了这个问题。我对正确缓存的想法是:克隆一个克隆,新的deque引用了原始的iter deque。很明显,这不会直接发生……至少不会直接发生。只要我的第一手克隆没有使用它的值,第二手克隆基本上会被正确缓存。如果第一手国际热核实验堆有任何消耗,那么此后由其制作的任何克隆都不能正确反映原始国际热核实验堆,而不是部分消耗的第一手。很抱歉,重新发布。你已经为我回答了这个问题。我关于正确缓存的想法真的需要一个新主题。如果您能给出所需行为的确切输入/输出示例,也许编写满足您需要的类似tee的函数就足够简单了。tee-like正是我对新主题的想法。我现在很幸运,我的代码在消费之前设置了所有的T恤。如果我没有意识到这对我的功能有多重要的话,可能会是一个很好的小错误。一个二手复制品对最初的迭代器一无所知。它将只生成第一手迭代器生成的值-&您不能再次使用第一手迭代器!就像你不应该在制作第一手teeit克隆后再次使用它一样。不管怎样,国际热核聚变实验堆也没有原始的德克——每个克隆体都有一个德克,彼此独立。很抱歉,但我仍然不清楚正确缓存对您意味着什么。给出一个准确的期望输入/输出示例,或就此放弃-你的最后一个例子很好地说明了这个问题。我对正确缓存的想法是:克隆一个克隆,新的deque引用了原始的iter deque。很明显,这不会直接发生……至少不会直接发生。只要我的第一手克隆没有使用它的值,第二手克隆基本上会被正确缓存。如果第一手国际热核实验堆有任何消耗,那么此后由其制作的任何克隆都不能正确反映原始国际热核实验堆,而不是部分消耗的第一手。很抱歉,重新发布。你已经为我回答了这个问题。我关于正确缓存的想法真的需要一个新主题。如果您能给出所需行为的确切输入/输出示例,也许编写满足您需要的类似tee的函数就足够简单了。tee-like正是我对新主题的想法。我现在很幸运,我的代码在消费之前设置了所有的T恤。如果我没有意识到这对我的功能有多重要的话,那以后可能会成为一个不错的小bug。