使用工作池和生成器对象异步生成排列 python

Asynchronously generating permutations using a pool of workers and a generator object python

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

所需结果:

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

其中 PRE 来自列表 'prefix'

从 "".join(x)

中找到 JOINEDPERMUTATION

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

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

REPETITIONS 我希望在范围 (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' 基本上没有用,因为它只会利用一个工人?为什么会在这里?

很难相信你没有收到错误本身,这东西应该疯狂地引发 RuntimeError。

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

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

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

这应该可以满足您的要求:

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() 只会利用一名工人的想法?您可能想查看 this question, especially this one

上的答案