我在python中有一个用于列表功率集的生成器,我想使用multiprocessing模块对这些集合的元素进行一些计算。我的代码如下:

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放在列表中,则可以使用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()


如果您的幂集非常大,则需要指定默认值以外的chunksize:1:


  chunksize参数与map()使用的参数相同
  方法。对于很长的可迭代对象,使用较大的块大小值可以
  使作业完成比使用默认值1快得多。


map函数使用以下算法,为您提供一个不错的选择:

chunksize, extra = divmod(len(iterable), len(pool_size) * 4)
if extra:
    chunksize += 1

10-07 15:08