为了账号安全,请及时绑定邮箱和手机立即绑定

用于多个参数的Python多处理池.map

用于多个参数的Python多处理池.map

偶然的你 2019-06-14 16:09:08
用于多个参数的Python多处理池.map在Python多处理库中,是否存在支持多个参数的pool.map的变体?text = "test"def harvester(text, case):     X = case[0]     text+ str(X)if __name__ == '__main__':     pool = multiprocessing.Pool(processes=6)     case = RAW_DATASET     pool.map(harvester(text,case),case, 1)     pool.close()     pool.join()
查看完整描述

3 回答

?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

这一问题的答案取决于版本和情况。对于Python的最新版本(自3.3以来),最普遍的答案是:塞巴斯蒂安.1它使用Pool.starmap方法,它接受一个参数元组序列。然后自动从每个元组中解压缩参数,并将它们传递给定的函数:

import multiprocessingfrom itertools import productdef merge_names(a, b):
    return '{} & {}'.format(a, b)if __name__ == '__main__':
    names = ['Brown', 'Wilson', 'Bartlett', 'Rivera', 'Molloy', 'Opie']
    with multiprocessing.Pool(processes=3) as pool:
        results = pool.starmap(merge_names, product(names, repeat=2))
    print(results)# Output: ['Brown & Brown', 'Brown & Wilson', 'Brown & Bartlett', ...

对于早期版本的Python,您需要编写一个帮助函数来显式地解压参数。如果你想用with,您还需要编写一个包装器来转换Pool变成上下文管理器。(多亏了μ子)指出这一点。)

import multiprocessingfrom itertools import productfrom contextlib import contextmanagerdef merge_names(a, b):
    return '{} & {}'.format(a, b)def merge_names_unpack(args):
    return merge_names(*args)@contextmanagerdef poolcontext(*args, **kwargs):
    pool = multiprocessing.Pool(*args, **kwargs)
    yield pool
    pool.terminate()if __name__ == '__main__':
    names = ['Brown', 'Wilson', 'Bartlett', 'Rivera', 'Molloy', 'Opie']
    with poolcontext(processes=3) as pool:
        results = pool.map(merge_names_unpack, product(names, repeat=2))
    print(results)# Output: ['Brown & Brown', 'Brown & Wilson', 'Brown & Bartlett', ...

在更简单的情况下,使用固定的第二个参数,您还可以使用partial,但仅限于Python2.7+。

import multiprocessingfrom functools import partialfrom contextlib import contextmanager@contextmanagerdef poolcontext(*args, **kwargs):
    pool = multiprocessing.Pool(*args, **kwargs)
    yield pool
    pool.terminate()def merge_names(a, b):
    return '{} & {}'.format(a, b)if __name__ == '__main__':
    names = ['Brown', 'Wilson', 'Bartlett', 'Rivera', 'Molloy', 'Opie']
    with poolcontext(processes=3) as pool:
        results = pool.map(partial(merge_names, b='Sons'), names)
    print(results)# Output: ['Brown & Sons', 'Wilson & Sons', 'Bartlett & Sons', ...

1.在很大程度上,这是他的回答所启发的,而他的回答可能反而应该被接受。但是,由于这一个被困在顶端,它似乎是最好的改进,为未来的读者。


查看完整回答
反对 回复 2019-06-14
?
红糖糍粑

TA贡献1815条经验 获得超6个赞

是否有池.map的变体支持多个参数?

Python 3.3包括pool.starmap()方法:

#!/usr/bin/env python3from functools import partialfrom itertools import repeatfrom multiprocessing import Pool, freeze_supportdef func(a, b):
    return a + bdef main():
    a_args = [1,2,3]
    second_arg = 1
    with Pool() as pool:
        L = pool.starmap(func, [(1, 1), (2, 1), (3, 1)])
        M = pool.starmap(func, zip(a_args, repeat(second_arg)))
        N = pool.map(partial(func, b=second_arg), a_args)
        assert L == M == Nif __name__=="__main__":
    freeze_support()
    main()

对于旧版本:

#!/usr/bin/env python2import itertoolsfrom multiprocessing import Pool, freeze_supportdef func(a, b):
    print a, bdef func_star(a_b):
    """Convert `f([1,2])` to `f(1,2)` call."""
    return func(*a_b)def main():
    pool = Pool()
    a_args = [1,2,3]
    second_arg = 1
    pool.map(func_star, itertools.izip(a_args, itertools.repeat(second_arg)))if __name__=="__main__":
    freeze_support()
    main()

输出量

1 1
2 1
3 1

注意itertools.izip()itertools.repeat()用在这里。

由于@unutbu提到的bug你不能用functools.partial()或者类似于Python2.6的功能,所以简单的包装函数func_star()应该明确定义。另见解决办法 建议uptimebox.


查看完整回答
反对 回复 2019-06-14
?
慕娘9325324

TA贡献1783条经验 获得超4个赞

我想下面的情况会更好

def multi_run_wrapper(args):
   return add(*args)def add(x,y):
    return x+yif __name__ == "__main__":
    from multiprocessing import Pool
    pool = Pool(4)
    results = pool.map(multi_run_wrapper,[(1,2),(2,3),(3,4)])
    print results

输出量

[3, 5, 7]


查看完整回答
反对 回复 2019-06-14
  • 3 回答
  • 0 关注
  • 3403 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信