使用multiprocessing.Pool.map时报TypeError: list与int不支持<=比较
问题复现代码
from multiprocessing import Pool def f(x,y): return x*y with Pool(4) as p: print(p.map(f,[2,2,2],[3,4,5]))
运行报错信息
TypeError Traceback (most recent call last) <ipython-input-25-e9ce49d0ccbf> in <module> 1 p = multiprocess.pool.Pool() 2 # result = p.map(for_multical,[N]*n,[k]*n) ----> 3 print(p.map(f,[2,2,2],[3,4,5])) 4 p.close() 5 p.join() D:\software\python\lib\site-packages\multiprocess\pool.py in map(self, func, iterable, chunksize) 362 in a list that is returned. 363 ''' --> 364 return self._map_async(func, iterable, mapstar, chunksize).get() 365 366 def starmap(self, func, iterable, chunksize=None): D:\software\python\lib\site-packages\multiprocess\pool.py in _map_async(self, func, iterable, mapper, chunksize, callback, error_callback) 483 484 task_batches = Pool._get_tasks(func, iterable, chunksize) --> 485 result = MapResult(self, chunksize, len(iterable), callback, 486 error_callback=error_callback) 487 self._taskqueue.put( D:\software\python\lib\site-packages\multiprocess\pool.py in __init__(self, pool, chunksize, length, callback, error_callback) 795 self._value = [None] * length 796 self._chunksize = chunksize --> 797 if chunksize <= 0: 798 self._number_left = 0 799 self._event.set() TypeError: '<=' not supported between instances of 'list' and 'int'
问题产生原因
报错核心是参数传位错误,同时存在函数调用逻辑问题:
multiprocessing.Pool.map的方法签名为map(func, iterable, chunksize=None),第三个位置参数要求传入整数类型的chunksize,用于指定每个任务块的拆分大小。代码中把第二个列表参数[3,4,5]作为第三个位置参数传入后,Python直接将这个列表赋值给了chunksize变量,后续代码执行chunksize <= 0判断时,拿列表和整数做比较,直接抛出类型错误。- 就算修正
chunksize传参,Pool.map也只会遍历单个可迭代对象,每次取出一个元素传给目标函数,而定义的f(x,y)需要两个入参,调用时会触发参数数量不匹配的错误。 - 第三方
multiprocess包的API和标准库multiprocessing完全对齐,因此会出现完全相同的报错。
修复方法
需要给目标函数传多个参数时,改用Pool.starmap方法,该方法支持传入元素为元组的可迭代对象,会自动将每个元组解包为位置参数传给目标函数,它的第三个位置参数才是chunksize。
修复后的代码如下:
from multiprocessing import Pool def f(x,y): return x*y if __name__ == '__main__': # Windows环境下多进程必须加主入口判断,避免递归创建进程 with Pool(4) as p: # 用zip将两个列表打包为(2,3),(2,4),(2,5)的元组序列,传给starmap print(p.starmap(f, zip([2,2,2],[3,4,5])))
运行后输出[6, 8, 10],符合预期。
注意:Windows系统下多进程代码必须放在
if __name__ == '__main__':作用域下,否则会触发递归创建进程的错误。
内容的提问来源于stack exchange,提问作者moonkeeper
相关产品推荐
相关产品推荐

