在python中并行迭代单个列表

时间:2015-04-08 07:32:15

标签: python parallel-processing iterator itertools

目标是使用 iter builtin函数同时对 parallel 中的单个sum & map进行计算< / strong>即可。也许使用(例如)itertools而不是经典for loops来分析通过iterator ...

到达的(LARGE)数据

在一个简单的示例案例中,我想计算ilen, sum_x & sum_x_sq

ilen,sum_x,sum_x_sq=iterlen(iter),sum(iter),sum(map(lambda x:x*x, iter))

但未将(大) iter转换为list(与iter=list(iter)一样)

n.b。使用sum & map和不使用for loops执行此操作,可能使用itertools和/或threading模块?

def example_large_data(n=100000000, mean=0, std_dev=1):
  for i in range(n): yield random.gauss(mean,std_dev)

- 编辑 -

非常具体:我正在好好看看itertools,希望有一个像map这样的双重功能可以做到这一点。例如:len_x,sum_x,sum_x_sq=itertools.iterfork(iter_x,iterlen,sum,sum_sq)

如果我非常具体:我正在寻找一个答案,&#34; iterfork&#34;的python源代码。过程

1 个答案:

答案 0 :(得分:2)

您可以使用itertools.tee将单个迭代器转换为三个迭代器,您可以将它们传递给三个函数。

iter0, iter1, iter2 = itertools.tee(input_iter, 3)
ilen, sum_x, sum_x_sq = count(iter0),sum(iter1),sum(map(lambda x:x*x, iter2))

工作,但内置函数sum(以及Python 2中的map)并未以支持并行迭代的方式实现。您调用的第一个函数将完全使用其迭代器,然后第二个函数将使用第二个迭代器,然后第三个函数将使用第三个迭代器。由于tee必须存储其输出迭代器之一所看到的值,而不是所有其他输出迭代器,这与从迭代器创建列表并将其传递给每个函数基本相同。

现在,如果您使用生成器函数,它们输出的每个值只消耗其输入中的单个值,您可以使用zip进行并行迭代。在Python 3中,mapzip都是生成器。问题是如何将sum变成生成器。

我认为你可以使用itertools.accumulate(在Python 3.2中添加)来获得你想要的东西。它是一个生成器,可以生成其输入的运行总和。以下是您如何使其适用于您的问题(我假设您的count函数应该是len的迭代器友好版本):

iter0, iter1, iter2 = itertools.tee(input_iter, 3)

len_gen = itertools.accumulate(map(lambda x: 1, iter0))
sum_gen = itertools.accumulate(iter1)
sum_sq_gen = itertools.accumulate(map(lambda x: x*x, iter2))

parallel_gen = zip(len_gen, sum_gen, sum_sq_gen)  # zip is a generator in Python 3

for ilen, sum_x, sum_x_sq in parallel_gen:
    pass    # the generators do all the work, so there's nothing for us to do here

# ilen_x, sum_x, sum_x_sq have the right values here!

如果您使用的是Python 2而不是3,那么您必须编写自己的accumulate生成器函数(在我上面链接的文档中有纯Python实现) ,并使用itertools.imapitertools.izip而非内置mapzip函数。