首页 > 解决方案 > 使用工人池和生成器对象python异步生成排列

问题描述

我需要让一些排列异步运行,以减少生成列表中所有可能排列的文件所需的时间。我曾多次尝试对此进行多重处理,但均未成功。

要求的结果:

包含以下格式的字符串列表的文件:PRE + JOINEDPERMUTATION

其中 PRE 来自列表“前缀”

从 "".join(x) 中找到 JINEDPERMUTATION

其中 x 是从排列(项目,重复)中找到的

ITEMS 是我需要检索排列的值列表

重复我希望在 range(8) 重复中找到此列表的每个排列

items=['a','b','c']
prefix=['one','two','three']
from itertools import permutations
from multiprocessing import Pool
pool=Pool(14)

def permutations(pre, repetitions, items):
    PERMS = [ pre + "".join(x) for x in permutations(items, repetitions) ]
    return PERMS

def result_collection(result):
    results.extend(result)
    return results

results=[]

args = ((pre, repetitions, items) for pre in prefix for repetitions in range(5))

for pre, repetitions, items in args:
    pool.apply_async(permutations, (pre, repetitions, items), callback=result_collection)
pool.close()
pool.join()

with open('file.txt','a',encoding='utf-8') as file:
    file.writelines(results)

我本身并没有收到错误,但是在使用列表运行该程序后,ITEMS 有 50 个元素,PREFIXES 有 5 个;8 小时后还没有完成,我不知道如何进一步调查。

一个快速的旁白查询,我是否认为在多处理模块中基本上没有使用“pool.map”,因为它只会利用一个工人?为什么会在这里?

标签: pythonmultiprocessinggeneratoritertoolspool

解决方案


很难相信你本身没有收到错误,这件事应该像疯了一样引发 RuntimeError 。

在一个新产生的进程中,产生它的模块被加载,即执行。这意味着您的代码尝试创建 14 个进程,每个进程都尝试创建 14 个进程,每个进程都尝试创建 14 个……您可能会在这里看到该模式的发展 :)

您必须将只能从主进程执行的所有内容放在一个__name__ == '__main__'块中。这将阻止在工作人员中执行这些代码部分,因为对他们来说,__name____mp_name__.

这样做将修复多处理部分,但还有另一个问题。您从 itertools 导入permutations,然后在命名空间中创建一个具有相同名称的函数,从而有效地覆盖来自 itertools 的函数。当您的进程调用您的functionpermutations时,该行将PERMS = [ pre + "".join(x) for x in permutations(items, repetitions) ]引发 TypeError 因为您在那里调用permutations函数,但使用两个参数,而不是函数定义所需的三个参数。

这应该做你想要的:

from itertools import permutations as it_perms
from multiprocessing import Pool
items=['a','b','c']
prefix=['one','two','three']


def permutations(pre, repetitions, items):
    PERMS = [ pre + "".join(x) for x in it_perms(items, repetitions) ]
    return PERMS

def result_collection(result):
    results.extend(result)
    return results


if __name__ == '__main__':
    pool = Pool(14)
    results = []

    args = ((pre, repetitions, items) for pre in prefix for repetitions in range(5))

    for pre, repetitions, items in args:
        pool.apply_async(permutations, (pre, repetitions, items), callback=result_collection)
    pool.close()
    pool.join()

    with open('file.txt','a',encoding='utf-8') as file:
        file.writelines(results)

至于您的侧面查询:您从哪里得到 pool.map() 只会利用一个工人的想法?你可能想检查这个问题的答案,尤其是这个问题


推荐阅读