是否有可能在多个用户之间“管道”消耗一台发电机?在
例如,通常有以下模式的代码:
def consumer1(iterator):
for item in iterator:
foo(item)
def consumer2(iterator):
for item in iterator:
bar(item)
myiter = list(big_generator())
v1 = consumer1(myiter)
v2 = consumer2(myiter)
在这种情况下,多个函数完全使用同一个迭代器,因此有必要在列表中缓存迭代器。由于每个使用者都耗尽迭代器,itertools.tee
是无用的。在
我经常看到这样的代码,我总是希望我能让消费者按顺序一次消费一个项目,而不是缓存整个迭代器。E、 g.:
consumer1
消耗myiter[0]
consumer2
消耗myiter[0]
consumer1
消耗myiter[1]
consumer2
消耗myiter[1]
如果我编一个语法,它应该是这样的:
^{pr2}$您可以使用线程或多处理和tee
d迭代器来接近,但是线程以不同的速度消耗,这意味着tee
中缓存的deque值可能会非常大。这里的重点不是利用并行性或加速任务,而是避免缓存迭代器的大段。在
在我看来,如果不修改消费者,这可能是不可能的,因为控制流在消费者中。然而,当使用者实际使用迭代器控制传递到迭代器的next()
方法时,那么也许有可能以某种方式反转控制流,以便迭代器一次阻塞一个使用者,直到它可以将它们全部输入为止?在
如果这是可能的,我还不知道怎么做。有什么想法吗?在
由于不更改消费者代码的限制(即在其中有一个循环),您只剩下两个选项:
itertools.tee
,其中一个缓冲区大小为1,它阻止服务项目i+1
,直到项目{没有其他选择。您无法实现以下所有目标,因为它们相互矛盾:
如果要重用生成的项,则必须将它们存储在的某个位置。在
如果更改消费者的代码是可以接受的,那么@monkey的解决方案显然是最简单和最直接的。在
这不管用吗?或者您需要整个迭代器,这样对每个迭代器的一个副本就不能工作了?如果是这样的话,那么我认为你要么必须创建一个副本,要么生成两次列表?在
相关问题 更多 >
编程相关推荐