我在python中有一个列表的powerset生成器,我想使用多处理模块对这些集合的元素进行一些计算。我的代码如下:
def powerset(seq):
'''Returns all the subsets of the list. This is a generator.'''
if len(seq) == 0:
yield seq
if len(seq) == 1:
yield seq
yield []
elif len(seq) > 1:
for item in powerset(seq[1:]):
yield [seq[0]]+item
yield item
def job(l):
# do some calculation with the list l
return do_some_hard_work(l)
def calculate():
pool_size = multiprocessing.cpu_count() * 2
pool = multiprocessing.Pool(processes=pool_size, maxtasksperchild=2)
pool_outputs = pool.map(job, powerset(list(range(1,10)))
pool.close()
pool.join()
return sum(pool_outputs)
问题是powerset-function是一个生成器,不起作用。但是我无法替换发生器,因为在计算需要很多时间和内存之前生成孔poweret。有谁知道如何解决这个问题?
答案 0 :(得分:0)
如果问题是你想避免将整个powerset放在一个列表中,你可以使用pool.imap
,它将一次消耗你的迭代器chunksize
元素,并将它们发送出去对于工作进程,而不是将整个事物转换为列表并将其整理出来。
pool_size = multiprocessing.cpu_count() * 2
pool = multiprocessing.Pool(processes=pool_size, maxtasksperchild=2)
pool_outputs = pool.imap(job, powerset(list(range(1,10))), chunksize=<some chunksize>)
pool.close()
pool.join()
如果您的powerset非常大,您需要指定除默认值之外的chunksize
,即1:
chunksize参数与map()使用的参数相同 方法。对于使用较大值的chunksize可以进行很长时间的迭代 使用默认值1来快速完成工作。
map
函数使用以下算法,让您了解好大小:
chunksize, extra = divmod(len(iterable), len(pool_size) * 4)
if extra:
chunksize += 1