繁体   English   中英

在python中并行遍历单个列表

[英]iterating over a single list in parallel in python

目的是同时使用builtin sum & map函数并行地对单个iter进行计算。 也许使用(类似) 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)

nb是否使用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)

如果我要非常具体:我只在寻找一个答案,即“ iterfork ”过程的python源代码。

您可以使用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功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM