2016-06-21 86 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 –