我想调用一个包含两个或更多参数的函数.在下面的示例中,我使用了lambda函数,并将ref定义为一个大小与numberlist相同、值相同的array.

1st Question:有更好的方法吗?在numberlist的大小可能是百万到十亿个元素的情况下,因此ref size必须遵循numberlist,这种方法不必要地占用宝贵的内存,我希望避免这种情况.我这样做是因为我读到map函数将终止其映射,直到到达最短的数组末端.

import concurrent.futures as cf

nmax = 10
numberlist = range(nmax)
ref = [5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
workers = 3


def _findmatch(listnumber, ref):    
    print('def _findmatch(listnumber, ref):')
    x=''
    listnumber=str(listnumber)
    ref = str(ref)
    print('listnumber = {0} and ref = {1}'.format(listnumber, ref))
    if ref in listnumber:
        x = listnumber
    print('x = {0}'.format(x))
    return x 

a = map(lambda x, y: _findmatch(x, y), numberlist, ref)
for n in a:
    print(n)
    if str(ref[0]) in n:
        print('match')

with cf.ProcessPoolExecutor(max_workers=workers) as executor:
    #for n in executor.map(_findmatch, numberlist):
    for n in executor.map(lambda x, y: _findmatch(x, ref), numberlist, ref):
        print(type(n))
        print(n)
        if str(ref[0]) in n:
            print('match')

运行上面的代码,我发现map函数能够实现我想要的结果.然而,当我把同样的条款转移到concurrent时.期货处理池执行器.map(),Python 3.5因以下错误而失败:

Traceback (most recent call last):
  File "/usr/lib/python3.5/multiprocessing/queues.py", line 241, in _feed
    obj = ForkingPickler.dumps(obj)
  File "/usr/lib/python3.5/multiprocessing/reduction.py", line 50, in dumps
    cls(buf, protocol).dump(obj)
_pickle.PicklingError: Can't pickle <function <lambda> at 0x7fd2a14db0d0>: attribute lookup <lambda> on __main__ failed

Question 2:为什么会发生此错误,以及如何获得并发.期货处理池执行器.map()调用具有多个参数的函数?

推荐答案

首先回答第二个问题,你会得到一个异常,因为像你正在使用的lambda函数是不可拾取的.由于Python使用pickle协议来序列化主进程和ProcessPoolExecutor的工作进程之间传递的数据,这是一个问题.不清楚你为什么要用lambda.你的lambda有两个参数,就像原始函数一样.你可以直接使用_findmatch而不是lambda,它应该可以工作.

with cf.ProcessPoolExecutor(max_workers=workers) as executor:
    for n in executor.map(_findmatch, numberlist, ref):
        ...

至于第一个问题,关于在不创建巨大列表的情况下传递第二个常量参数,可以用几种方法解决.一种方法可能是使用itertools.repeat创建一个iterable对象,该对象在迭代时永远重复相同的值.

但更好的方法可能是编写一个额外的函数,为您传递常量参数.(也许这就是为什么你try 使用lambda函数?)如果您使用的函数可以在模块的顶级命名空间中访问,那么它应该可以工作:

def _helper(x):
    return _findmatch(x, 5)

with cf.ProcessPoolExecutor(max_workers=workers) as executor:
    for n in executor.map(_helper, numberlist):
        ...

Python-3.x相关问答推荐

Python gpsd客户端

如何使用Python将嵌套的XML转换为CSV

按长度和字母数字对Pandas 数据帧列进行排序

在 Python 中比较和排序列之间的值(带有不匹配列)

Django中自动设置/更新字段

Python,Web 从交互式图表中抓取数据

如何转置和 Pandas DataFrame 并命名新列?

为什么 Sympy 不能解决我的非线性系统? Python 解释器一直在执行,直到我终止进程

为什么 numpy 的 `np.char.encode` 会将一个空的 unicode 数组变成一个空的 `float64` 数组?

Python:如何从句子/段落中提取地址(非正则表达式方法)?

正则表达式从文本文件中捕获包含制表符/空格和子字符串的部分字符串

Dask worker post-processing

python tkInter 浏览文件夹按钮

有没有更好的方法来判断一个数字是否是两个数字的范围

为 python3 安装 opencv

如何在 Python 中计算 cohen 的 d?

Python configparser 不会接受没有值的键

如何避免使用我的 python 包构建 C 库?

如何修复:cx_Oracle.DatabaseError:DPI-1047:找不到 64 位 Oracle 客户端库 - Python

Python:如何在 Windows 资源管理器中打开文件夹(Python 3.6.2、Windows 10)