首页 > 解决方案 > 最佳地从输入系列生成2个系列

问题描述

考虑一下:

A,B=[],[]
for i in range(0,n):
    item=manipulate(data,i)
    A += [nextSerieA(data,i,item)]
    B += [nextSerieB(data,i,item)]

for a in A:
    doSmt(a)

for b in B:
    doSmt(b)

ifn是非常大的数字并且manipulate需要很长时间才能执行 ill 等待永远doSmt被调用。

所以我想使用生成器来doSmt更快地开始被调用,例如:

def genA():
    for i in range(0,n):
        item=manipulate(data,i)
        yield nextSerieA(data,i,item)

def genB():
    for i in range(0,n):
        item=manipulate(data,i)
        yield nextSerieB(data,i,item)

for a in genA():
    doSmt(a)

for b in genB():
    doSmt(b)

这种方法的问题在于manipulate,输入系列中的每个项目都会被调用两次,如果操作是繁重的操作,它是多余的,我想避免它。

迈向最佳代码的下一步将是:

def manipulate():
    for i in range(0,n):
        yield i,manipulate(data,i)

def genA():
    for i,item in manipulate():
        yield nextSerieA(data,i,item)

def genB():
    for i,item in manipulate():
        yield nextSerieB(data,i,item)

for a in genA():
    doSmt(a)

for b in genB():
    doSmt(b)

manipulate每个输入仍会被调用两次。什么是获得我想要的东西并确保其最佳的正确方法,即manipulate每个输入项调用一次?

标签: python

解决方案


您可以使用itertools.tee,它在后台使用队列来存储生成的项目。

def manipulate():
    for i in range(0,n):
        yield manipulate(data,i)
(genA,genB) = itertools.tee(manipulate())

它将节省一些计算资源,因为操作将被称为每个项目一个。

但是,如果处理是如示例中的顺序处理(第一个处理 genA 和 genB),则将需要大量辅助存储。


推荐阅读