Понимание параллельного списка с использованием карты пула
У меня есть понимание списка:
thingie=[f(a,x,c) for x in some_list]
который я распараллеливаю следующим образом:
from multiprocessing import Pool
pool=Pool(processes=4)
thingie=pool.map(lambda x: f(a,x,c), some_list)
но я получаю следующую ошибку:
_pickle.PicklingError: Can't pickle <function <lambda> at 0x7f60b3b0e9d8>:
attribute lookup <lambda> on __main__ failed
Я пытался установить pathos
пакет, который, очевидно, решает эту проблему, но когда я пытаюсь импортировать его, я получаю сообщение об ошибке:
ImportError: No module named 'pathos'
2 ответа
Хорошо, так что этот ответ только для протокола, я выяснил это с автором вопроса во время обсуждения комментариев.
multiprocessing
необходимо транспортировать каждый объект между процессами, поэтому он использует pickle
сериализовать его в одном процессе и десериализовать в другом. Все работает хорошо, но pickle
не может сериализоваться lambda
, AFAIR это так, потому что pickle
нужен источник функций для его сериализации, и lambda
не будет, но я не уверен на 100% и не могу процитировать свой источник.
Это не будет проблемой, если вы используете map()
на 1 аргумент функции - вы можете передать эту функцию вместо lambda
, Если у вас есть больше аргументов, как в вашем примере, вам нужно определить некоторую оболочку с def
ключевое слово:
from multiprocessing import Pool
def f(x, y, z):
print(x, y, z)
def f_wrapper(y):
return f(1, y, "a")
pool = Pool(processes=4)
result = pool.map(f_wrapper, [7, 9, 11])
Непосредственно перед тем, как закрыть это, я нашел другой способ сделать это с помощью Python 3, используя functools,
скажи у меня есть функция f
с тремя переменными f(a,x,c)
один из которых я хочу сказать x
, Я могу использовать следующий код, чтобы сделать то, что предлагает @FilipMalczak:
import functools
from multiprocessing import Pool
f1=functools.partial(f,a=10)
f2=functools.partial(f2,c=10)
pool=Pool(processes=4)
final_answer=pool.map(f2,some_list)