Search code examples
pythonpython-3.xparallel-processingmultiprocessingpython-multiprocessing

pool.map: TypeError map() takes from x to y positional arguments but z were given


I'm trying to parallelize a function in my program for time measurement purposes, but I get an error and I don't know how to fix it.

Here's the code:

def evolucionAutomata(automata, regla, numero_evoluciones):
    if(numero_evoluciones == 0):
        return 0
    with Pool(4) as p:
        automataEvolucionado = list(p.map(obtenerVecindario, automata, rotarDerecha(automata, 1), rotarIzquierda(automata, 1), lista_regla))**
    print(automataEvolucionado)
    evolucionAutomata(automataEvolucionado, regla, numero_evoluciones - 1)

def obtenerVecindario(casilla, casillaDerecha, casillaIzquierda, regla):
    if( "X" in casilla ):
        casillaBinaria = casilla.replace("X", "1")
    if( "O" in casilla):
        casillaBinaria = casilla.replace("O", "0")
    if ("X" in casillaDerecha):
        casillaBinariaDerecha = casillaDerecha.replace("X", "1")
    if ("O" in casillaDerecha):
        casillaBinariaDerecha = casillaDerecha.replace("O", "0")
    if ("X" in casillaIzquierda):
        casillaBinariaIzquierda = casillaIzquierda.replace("X", "1")
    if ("O" in casillaIzquierda):
        casillaBinariaIzquierda = casillaIzquierda.replace("O", "0")
    vecindario = []
    vecindario.append(casillaBinariaDerecha)
    vecindario.append(casillaBinaria)
    vecindario.append(casillaBinariaIzquierda)
    vecindario = list(map(int, vecindario))
    valorRetorno = evaluarVecindario(vecindario, regla)
    return valorRetorno

rotarDerecha and rotarIzquierda functions, rotates the automaton.

The error:

automataEvolucionado = list(p.map(obtenerVecindario, automata, rotarDerecha(automata, 1), rotarIzquierda(automata, 1), lista_regla))
TypeError: map() takes from 3 to 4 positional arguments but 6 were given

I've wrote the multiprocessed code from the basic example of multiprocessing in python from python multiprocessing documentation.

Thanks in advance.


Solution

  • The error comes because Pool.map() is just expecting one argument for the argument-iterable, but you try to pass more.

    Signature: Pool.map(func, iterable, chunksize=None)

    You need to combine (zip) your arguments into one iterable. Every item of this task-iterable should contain the arguments for one function call. Then you use .starmap() instead of .map() to let it unpack and map the argument-tuples to the target-function parameters.

    from multiprocessing import Pool
    
    
    def f(arg1, arg2):
        print(arg1, arg2)
    
    
    if __name__ == '__main__':
    
        N = 10
    
        args1 = [*range(N)]
        args2 = [100] * N  # make argument iterables same length
    
        # create list of argument tuples for individual function calls
        tasks = [*zip(args1, args2)]
        # [(0, 100), (1, 100), (2, 100), ..., (9, 100)]
    
        with Pool(4) as pool:
            pool.starmap(f, iterable=tasks)
    

    Python 2.7: How to compensate for missing pool.starmap?