Python在池映射中使用列表/多个参数

Python Using List/Multiple Arguments in Pool Map

我试图将一个列表作为参数传递给pool.map(co_refresh, input_list)。但是,pool.map没有触发co_refresh功能。也没有返回错误。这看起来像是一个过程。

原始代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from multiprocessing import Pool
import pandas as pd
import os

account='xxx'
password='xxx'
threads=5
co_links='file.csv'

input_list=[]

pool = Pool(processes=threads)
def co_refresh(url, account, password, outputfile):

    print(url + ' : ' + account + ' : ' + password + ' : ' + outputfile)

    return;

link_pool = pd.read_csv(co_links, skipinitialspace = True)

for i, row in link_pool.iterrows():

    ln = (row.URL, account, password, os.path.join('e:/', row.File_Name.split('.')[0] + '.csv'))

    input_list.append(ln)

pool.map(co_refresh, input_list)

pool.close()

但是,它从未触发函数co_refresh。如何使用列表作为要传递给函数的参数?

旧问题(简化):

我有下面的输入列表,它是listlist

1
2
3
[a1, b1, c1, d1]
[a2, b2, c2, d2]
[a3, b3, c3, d3]

我的功能如下:

1
2
3
def func(a, b, c, d)
   ###
    return;

我想对这个函数使用多进程func

1
2
3
4
from multiprocessing import Pool
pool = Pool(processes=5)
pool.map(func, input_list)
pool.close()

但是,它从未触发函数func。如何使用列表作为要传递给函数的参数?


在声明Pool之前,您应该定义您的工作函数,当您声明Pool时,从该点分叉的子工作进程,工作进程不会执行超出该行的代码,因此看不到您的工作函数。

另外,您最好用pool.starmap替换pool.map,以适应您的输入。

一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
from multiprocessing import Pool

def co_refresh(a, b, c, d):
    print(a, b, c, d)

input_list = [f'a{i} b{i} c{i} d{i}'.split() for i in range(4)]
# [['a0', 'b0', 'c0', 'd0'], ['a1', 'b1', 'c1', 'd1'], ['a2', 'b2', 'c2', 'd2'], ['a3', 'b3', 'c3', 'd3']]

pool = Pool(processes=3)
pool.starmap(co_refresh, input_list)
pool.close()


考虑下面的代码

1
2
3
4
5
6
7
8
9
from multiprocessing.pool import Pool

data = [["a1","b1","c1","d1"],
        ["a2","b2","c2","d2"],
        ["a3","b3","c3","d3"], ]


def someaction(a, b=1, c=2, d=3):
    print(a, b, c, d)

当您在脚本中使用池调用它时

1
2
pool = Pool(4)
pool.map(someaction, data)

输出为

1
2
3
['a1', 'b1', 'c1', 'd1'] 1 2 3
['a2', 'b2', 'c2', 'd2'] 1 2 3
['a3', 'b3', 'c3', 'd3'] 1 2 3

因此,a获取数组,其余所有参数都不传递。pool.map希望一个函数只有一个参数。因此,要使您的案例工作,您需要创建一个包装函数

1
2
def someaction_wrapper(data):
    someaction(*data)

然后在池中调用这个包装函数。现在你用

1
2
pool = Pool(4)
pool.map(someaction_wrapper, data)

输出是

1
2
3
a1 b1 c1 d1
a2 b2 c2 d2
a3 b3 c3 d3

我相信这就是你想要的


Georgexsh的答案在python 3中非常有效;关键是starmap允许向函数传递多个参数。

但是,如果您使用python 2,您将需要在这里的问题下使用ahmed在注释中提到的pythonclassic解包。

在我的例子中,我只需要在函数中首先"登记"参数。

1
2
3
4
def func(args)
   (a, b, c, d) = args
   # You can then use a, b, c, d in your function
    return;