【问题标题】:executing n iterations of for loop in parallel并行执行 n 次 for 循环迭代
【发布时间】: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的方式实现这一点?

【问题讨论】:

  • 多处理

标签: python python-2.7 multiprocessing


【解决方案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']
    

    【讨论】: