2010-12-16 25 views
11

En Python, el módulo multiprocessing se puede utilizar para ejecutar una función en un rango de valores en paralelo. Por ejemplo, esto produce una lista de las primeras 100000 evaluaciones de f.Multiproceso de Python una función con varias entradas

def f(i): 
    return i * i 

def main(): 
    import multiprocessing 
    pool = multiprocessing.Pool(2) 
    ans = pool.map(f, range(100000)) 

    return ans 

¿Se puede hacer algo similar cuando f toma múltiples entradas pero solo se varía una variable? Por ejemplo, ¿cómo se paralelizar esto:

def f(i, n): 
    return i * i + 2*n 

def main(): 
    ans = [] 
    for i in range(100000): 
     ans.append(f(i, 20)) 

    return ans 

Respuesta

11

Existen varias formas de hacerlo. En el ejemplo dado en la pregunta, usted podría definir una función de contenedor

def g(i): 
    return f(i, 20) 

y pasar esta envoltura para map(). Un enfoque más general es tener una envoltura que tiene un solo argumento tupla y desempaqueta la tupla a múltiples argumentos

def g(tup): 
    return f(*tup) 

o utilizar una expresión lambda equivalente: lambda tup: f(*tup).

-3

Usted puede utilizar currificación del pobre (también conocido como envolverlo):

new_f = lambda x: f(x, 20) 

luego llamar a new_f(i).

+3

Thils * no * trabajará con el mapa de multiprocesamiento, porque eso no admite funciones que no son "importables" (usando la herramienta de pickle) – Lagerbaer

21

Puede utilizar functools.partial

def f(i, n): 
    return i * i + 2*n 

def main(): 
    import multiprocessing 
    pool = multiprocessing.Pool(2) 
    ans = pool.map(functools.partial(f, n=20), range(100000)) 

    return ans 
3

Si utiliza el tenedor de multiprocessing, llamado pathos, puede obtener piscinas que tienen múltiples argumentos ... y también tomar lambda funciones. Lo bueno de esto es que no tienes que modificar tus construcciones de programación para que funcionen en paralelo.

>>> def f(i, n): 
... return i * i + 2*n 
... 
>>> from itertools import repeat 
>>> N = 10000 
>>> 
>>> from pathos.pools import ProcessPool as Pool 
>>> pool = Pool() 
>>> 
>>> ans = pool.map(f, xrange(1000), repeat(20)) 
>>> ans[:10] 
[40, 41, 44, 49, 56, 65, 76, 89, 104, 121] 
>>> 
>>> # this also works 
>>> ans = pool.map(lambda x: f(x, 20), xrange(1000)) 
>>> ans[:10] 
[40, 41, 44, 49, 56, 65, 76, 89, 104, 121] 
Cuestiones relacionadas