并行使用两个迭代器

时间:2014-02-21 21:41:02

标签: python parallel-processing

假设我有两个迭代器,我想计算

fancyoperation1(iter1), fancyoperation2(iter2)

通常情况下,我只会使用fancyoperation1(iter1), fancyoperation2(iter2)。但是,如果这些迭代器链接到单个源,也许是来自单个迭代器的tee d,那么如果不在内存中保留大量临时数据,我就无法做到这一点。在这种情况下,我知道几个选项:

  • 我可以将fancyoperation1fancyoperation2重写为同时执行这两项功能的单个函数,但这可能是很多代码重复,我可能无法理解或拥有源代码要么是功能。此外,这需要为每对操作重新完成。
  • 我可以使用线程。同步可能在辅助函数中写入一次,只要我不需要经常切换线程,开销可能不会太差。
  • 我可以在内存中保留大量临时数据。
但是,我并不喜欢这些选项的缺点。有没有办法在一个线程中执行我想要的操作,而无需重写内容或使用大量内存?我尝试用协同程序来做,但Python的yield似乎不够强大。

(我目前没有这个问题,但我想知道如果它出现该怎么办。)

1 个答案:

答案 0 :(得分:3)

你绝对可以使用协同程序,它只是稍微不方便(但在光明的一面,你可以保持它们分开,并可以保持大多数代码不变)。将花哨操作更改为无参数,并重复使用yield(作为表达式)来获取数据,而不是接受参数并迭代它。换句话说,改变这个:

def fancyoperation1(it):
    for x in it:
        ...
    cleanup()

# into something like this

def fancyoperation1():
    while True:
        try:
            x = yield
        except GeneratorExit:
            break
        ...
    cleanup()

当然,如果没有完成迭代后的清理会更容易。 您可以使用这些(假设为iter1, iter2 = tee(underlying_iter)):

f1, f2 = fancyoperation1(), fancyoperation2()
f1.send(None) # start coroutines
f2.send(None)

for x in underlying_iterator:
    f1.send(x)
    f2.send(x)
f1.close()
f2.close()