2016-06-21 89 views
3

我有以下功能和字典解析:並行化字典解析

def function(name, params): 
    results = fits.open(name) 
    <do something more to results> 
    return results 

dictionary = {name: function(name, params) for name in nameList} 

,並希望這種並行。任何簡單的方法來做到這一點?

here我發現可以使用multiprocessing模塊,但無法理解如何讓它將我的結果傳遞給我的字典。

備註:如果可能,請給出可應用於返回結果的函數的答案。

注2::在主要操縱擬合文件和分配結果的一類

UPDATE

因此,這裏對我來說到底有什麼工作(從@code_onkel答案):使用tqdm

def function(name, params): 
    results = fits.open(name) 
    <do something more to results> 
    return results 

def function_wrapper(args): 
    return function(*args) 

params = [...,...,..., etc]  

p = multiprocessing..Pool(processes=(max([2, mproc.cpu_count() // 10]))) 
args_generator = ((name, params) for name in names) 

dictionary = dict(zip(names, p.map(function_wrapper, args_generator))) 

只有部分工作,因爲我可以用我的自定義欄爲tqdm恢復到默認酒吧僅迭代。

+0

好像你可以使用'Pool.map'到'nameList'上,返回2個元組''(name,function(name,params))'',然後連接結果並使用它創建一個字典... – mgilson

+0

The短語是「詞典理解」,而不是「綜合詞典」。 – user2357112

回答

4

字典理解本身不能並行化。以下是如何在Python 2.7中使用multiprocessing模塊的示例。

from __future__ import print_function 
import time 
import multiprocessing 

params = [0.5] 

def function(name, params): 
    print('sleeping for', name) 
    time.sleep(params[0]) 
    return time.time() 

def function_wrapper(args): 
    return function(*args) 

names = list('onecharNAmEs') 

p = multiprocessing.Pool(3) 
args_generator = ((name, params) for name in names) 
dictionary = dict(zip(names, p.map(function_wrapper, args_generator))) 
print(dictionary) 
p.close() 

這適用於任何功能,但restrictions of the multiprocssing module適用。最重要的是,作爲參數和返回值傳遞的類以及要並行化的函數本身必須在模塊級定義,否則(de)序列化程序將無法找到它們。包裝函數是必需的,因爲function()需要兩個參數,但Pool.map()只能使用一個參數處理函數(如內置的map()函數)。

使用Python> 3.3,可以使用Pool作爲上下文管理器和starmap()函數來簡化它。

from __future__ import print_function 
import time 
import multiprocessing 

params = [0.5] 

def function(name, params): 
    print('sleeping for', name) 
    time.sleep(params[0]) 
    return time.time() 

names = list('onecharnamEs') 

with multiprocessing.Pool(3) as p: 
    args_generator = ((name, params) for name in names) 
    dictionary = dict(zip(names, p.starmap(function, args_generator))) 

print(dictionary) 

這是with塊的更可讀的版本:

with multiprocessing.Pool(3) as p: 
    args_generator = ((name, params) for name in names) 
    results = p.starmap(function, args_generator) 
    name_result_tuples = zip(names, results) 
    dictionary = dict(name_result_tuples) 

Pool.map()功能是用於功能與單個參數,這就是爲什麼在3.3中加入Pool.starmap()功能。

+0

似乎不適用於我,在運行代碼時出現第14行(出現with)錯誤時出現'AttributeError:__exit_ _',有任何想法爲什麼?另外,在不同的機器上獲得'AttributeError:'Pool'對象沒有屬性「starmap」' – jorgehumberto

+0

在版本3.3中添加了池作爲上下文管理器和starmap()的使用。我將編輯答案。 –

+0

示例應該現在可以使用2.7 –