考虑这个:
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
每个输入项调用一次?
答案 0 :(得分:1)
您可以使用itertools.tee,它使用幕后的队列来存储生成的项目。
def manipulate():
for i in range(0,n):
yield manipulate(data,i)
(genA,genB) = itertools.tee(manipulate())
这将节省一些计算资源,因为操纵将被称为一项。
但是,如果像示例中那样处理是顺序的(第一处理genA和genB),则将需要大量辅助存储。