使用池映射的并行列表理解
parallel list comprehension using Pool map
我有一个列表理解:
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'
好的,所以这个答案只是为了记录,我已经在评论对话中与问题的作者想通了。
multiprocessing
需要在进程之间传输每个对象,所以它使用 pickle
在一个进程中序列化它并在另一个进程中反序列化。一切正常,但 pickle
无法序列化 lambda
。 AFAIR 之所以如此,是因为 pickle
需要函数源来序列化它,而 lambda
不会有它,但我不是 100% 确定,也不能引用我的源。
如果您在 1 个参数函数上使用 map()
不会有任何问题 - 您可以传递该函数而不是 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)
我有一个列表理解:
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'
好的,所以这个答案只是为了记录,我已经在评论对话中与问题的作者想通了。
multiprocessing
需要在进程之间传输每个对象,所以它使用 pickle
在一个进程中序列化它并在另一个进程中反序列化。一切正常,但 pickle
无法序列化 lambda
。 AFAIR 之所以如此,是因为 pickle
需要函数源来序列化它,而 lambda
不会有它,但我不是 100% 确定,也不能引用我的源。
如果您在 1 个参数函数上使用 map()
不会有任何问题 - 您可以传递该函数而不是 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)