2016-06-21 15 views
3

ich die folgende Funktion und Wörterbuch Verständnis haben:Parallelisierung ein Wörterbuch Verständnis

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

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

und möchte dies parallelisieren. Irgendein einfacher Weg, dies zu tun?

In here Ich habe gesehen, dass das multiprocessing Modul verwendet werden kann, aber konnte nicht verstehen, wie es meine Ergebnisse an mein Wörterbuch weitergeben kann.

HINWEIS: Wenn möglich, geben Sie bitte eine Antwort, die auf jede Funktion angewendet werden kann, die ein Ergebnis zurückgibt.

ANMERKUNG 2: das ist Manipulation vor allem die Anfälle am Ende für mich die Ergebnisse in einer Klasse

UPDATE

Also hier ist, was funktioniert hat (von @code_onkel Antwort-Datei) und die Zuordnung:

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

mit tqdm funktionierte nur teilweise, da ich meine benutzerdefinierte Bar nutzen könnte als tqdm mit den Iterationen nur auf einen Standard bar zurückkehrt.

+0

Scheint so, als könnten Sie 'Pool.map' über' nameList' verwenden, 2 Tupel '(name, function (name, params))' 'zurückgeben und dann die Ergebnisse verketten und daraus ein ... – mgilson

+0

Begriff ist "dict Verständnis", nicht "umfassendes Wörterbuch". – user2357112

Antwort

4

Das Wörterbuch Verständnis selbst kann nicht parallelisiert werden. Hier ist ein Beispiel, wie man das multiprocessing Modul mit Python 2.7 benutzt.

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

Dies funktioniert mit jeder Funktion, obwohl die gelten. Am wichtigsten ist, dass die Klassen, die als Argumente und Rückgabewerte übergeben werden, sowie die Funktion, die selbst parallelisiert werden soll, auf der Modulebene definiert werden müssen, andernfalls wird der (De-) Serialisierer sie nicht finden. Die Wrapper-Funktion ist notwendig, da function() zwei Argumente benötigt, aber Pool.map() nur Funktionen mit einem Argument verarbeiten kann (wie die eingebaute map() Funktion).

Mit Python> 3.3 kann es vereinfacht werden, indem Pool als Kontextmanager und die starmap() Funktion verwendet wird.

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) 

Dies ist eine besser lesbare Version des with Block:

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) 

Die Pool.map() Funktion für Funktionen mit einem einzigen Argument ist, das ist, warum die Pool.starmap() Funktion in 3.3 hinzugefügt wurde.

+0

scheint nicht für mich zu arbeiten, einen "AttributeError: _ _exit_ _" in Zeile 14 (Begin von mit) Fehler beim Ausführen Ihres Codes, eine Idee warum? Auf einem anderen Rechner bekommt 'AttributError:' Pool 'kein Attribut' starmap '' – jorgehumberto

+0

Die Verwendung des Pools als Kontextmanager und die starmap() wurden in Version 3.3 hinzugefügt. Ich werde die Antwort bearbeiten. –

+0

Beispiel sollte jetzt mit 2.7 funktionieren –

Verwandte Themen