python concurrency iterator future map-function

python - Pasa múltiples parámetros a concurrent.futures.Executor.map?



concurrency iterator (2)

El concurrent.futures.Executor.map toma un número variable de iterables desde los cuales se llama la función dada. ¿Cómo debería llamarlo si tengo un generador que produce tuplas que normalmente se desempaquetan?

Lo siguiente no funciona porque cada una de las tuplas generadas se presenta como un argumento diferente para mapear:

args = ((a, b) for (a, b) in c) for result in executor.map(f, *args): pass

Sin el generador, los argumentos deseados para mapear podrían verse así:

executor.map( f, (i[0] for i in args), (i[1] for i in args), ..., (i[N] for i in args), )


Un argumento que se repite, un argumento en c

from itertools import repeat for result in executor.map(f, repeat(a), c): pass

Necesidad de desempacar artículos de c , y puede desempaquetar c

from itertools import izip for result in executor.map(f, *izip(*c)): pass

Necesito desempacar artículos de c , no puedo desempacar c

  1. Cambie f para tomar un solo argumento y descomprimir el argumento en la función.
  2. Si cada elemento en c tiene un número variable de miembros, o está llamando f solo unas pocas veces:

    executor.map(lambda args, f=f: f(*args), c)

    Define una nueva función que desempaqueta cada elemento de c y llama a f . El uso de un argumento predeterminado para f en la lambda hace que f sea ​​local dentro de la lambda y así reduce el tiempo de búsqueda.

  3. Si tiene un número fijo de argumentos, y necesita llamar a f muchas veces:

    from collections import deque def itemtee(iterable, n=2): def gen(it = iter(iterable), items = deque(), next = next): popleft = items.popleft extend = items.extend while True: if not items: extend(next(it)) yield popleft() return [gen()] * n executor.map(f, *itemtee(c, n))

Donde n es el número de argumentos para f . Esto es una adaptación de itertools.tee .


Debe eliminar el * en la llamada de map :

args = ((a, b) for b in c) for result in executor.map(f, args): pass

Esto llamará f , len(args) veces, donde f debería aceptar un parámetro. Si desea que f acepte dos parámetros, puede usar una llamada lambda como:

args = (a, b for b in c) for result in executor.map(lambda p: f(*p), args): pass