最佳地从输入序列生成2个系列

时间:2019-03-03 07:19:08

标签: python

考虑这个:

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)

如果n的数量很大,并且manipulate花费很长时间来执行恶意等待,以等待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每个输入项调用一次?

1 个答案:

答案 0 :(得分:1)

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

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

这将节省一些计算资源,因为操纵将被称为一项。

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