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
- Cambie
fpara tomar un solo argumento y descomprimir el argumento en la función. Si cada elemento en
ctiene un número variable de miembros, o está llamandofsolo unas pocas veces:executor.map(lambda args, f=f: f(*args), c)Define una nueva función que desempaqueta cada elemento de
cy llama af. El uso de un argumento predeterminado parafen lalambdahace quefsea local dentro de lalambday así reduce el tiempo de búsqueda.Si tiene un número fijo de argumentos, y necesita llamar a
fmuchas 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