[英]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中, map
和zip
都是生成器。 问题是如何使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.imap
和itertools.izip
而不是内置的map
和zip
功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.