2014-08-29 64 views
1

我有一個python列表的powerset生成器,我想對使用多處理模塊的這些設置的元素進行一些計算。我的代碼如下所示:在多處理模式下迭代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函數是一個生成器,並且不起作用。但是我不能代替發電機,因爲在計算需要很多時間和記憶之前產生孔電力。有沒有人知道我如何解決這個問題?

+0

_「一個發電機,這將無法正常工作」_從我可以看到一個小列表中,它提供了所需的答案。什麼是「不工作」? – 2014-08-29 12:14:20

+0

您可以將生成器傳遞給'pool.map',只需知道它將在任何項目發送到工作進程之前轉換爲列表。 – dano 2014-08-29 13:46:29

回答

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() 

如果您冪是非常大的,你會想比默認,這是1到指定chunksize其他:

的CHUNKSIZE參數是一樣的地圖中使用的() 方法。對於使用CHUNKSIZE一個較大的值可以 使工作完全不是使用1

默認值map函數使用以下算法快得多很長iterables,給你一個很好的大小的想法:

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

謝謝!這正是我正在尋找的! – Markus 2014-08-30 13:22:47