并行执行 n 次 for 循环迭代

Posted

技术标签:

【中文标题】并行执行 n 次 for 循环迭代【英文标题】:executing n iterations of for loop in parallel 【发布时间】:2020-07-17 01:30:05 【问题描述】:

假设我们在python中有一个嵌套的for循环,其中最里面的循环调用了一些函数fun

for x1 in ['a','b','c','d','e']:
    for x2 in [1,2,3]:
        fun(x1,x2)

如何重写,使funn 调用并行执行? IE。对于n==2,执行顺序为:

fun('a',1)fun('a',2) 并行运行。 当其中一个终止时,fun('a',3) 将启动 当其中一个终止时,fun('b',1) 将启动 ...等等

如何以最pythonic的方式实现这一点?

【问题讨论】:

多处理 【参考方案1】:

您可以使用multiprocessing 模块:

from multiprocessing import Pool
from itertools import product

if __name__ == "__main__":
    l1 = ['a', 'b', 'c', 'd', 'e']
    l2 = [1, 2, 3]
    n = 2
    with Pool(n) as pool:
        pool.starmap(fun, product(l1, l2))

使用product,我们连续创建所有对:

>>> list(product(['a', 'b'], [1, 2]))
[('a', 1), ('a', 2), ('b', 1), ('b', 2)]

然后,我们可以使用n 进程创建一个Pool,并使用starmap 函数将每一对传递给fun

通过创建Pool 并传递第一个参数n,我们拥有n 进程,这些进程按顺序从product 中获取每个元素,因此这会产生您正在寻找的效果——只要其中一个释放,它将占用下一行。

【讨论】:

【参考方案2】:

在列表推导中组合参数。然后你可以使用multiprocessing.Pool.starmap 来调用一个有多个参数的函数。

from multiprocessing import Pool

x1 = ['a','b','c','d','e']
x2 = [1,2,3]

param_combinations = [(i, j) for i in x1 for j in x2] 

def func(x, y):
    return f'x_y'

with Pool(processes=3) as p:
    results = p.starmap(func, param_combinations)

>>>results
['a_1',
 'a_2',
 'a_3',
 'b_1',
 'b_2',
 'b_3',
 'c_1',
 'c_2',
 'c_3',
 'd_1',
 'd_2',
 'd_3',
 'e_1',
 'e_2',
 'e_3']

【讨论】:

以上是关于并行执行 n 次 for 循环迭代的主要内容,如果未能解决你的问题,请参考以下文章

如何在 shell 中实现并行执行

并行化只需要在每 X 次迭代中运行的慢速函数,以免降低循环速度

用一个线程做一个部分,用多个线程做一个 for 循环

并行执行比顺序执行慢,即使代码“很重”

如何在 C++ 中并行化一个 for 循环,只创建一次线程池

如何在 for 循环中并行处理。我的代码不正确地并行操作