3

我正在尝试使用多处理pool.map来加速函数的执行,但可迭代不是该函数的第一个参数。Lambda 不起作用,因为它们不可腌制。我试图用来functools.partial创建一个新函数,但它失败了TypeError。下面是一个非常简单的示例,结果相同。如果我将参数 order 切换为f(i, s1, s2),它会按预期工作。

为什么参数顺序在这里很重要?当我阅读文档时,这对我来说并不明显。

我有什么选择(除了明显的改变原始功能)?

import multiprocessing
from functools import partial


def f(s1, s2, i):
    return [s1] + [s2]*i

def main():
    # other code... constants for f aren't known until runtime
    pool = multiprocessing.Pool()
    func = partial(f, s1='a', s2='c')
    for strings in pool.map(func, range(10)):
        print(strings)
    pool.close()
    pool.join()

if __name__ == '__main__':
    main()

更新:我能想到的最好的方法是在模块级别创建一个包装器来切换参数顺序,然后是包装器的一部分。看起来一点也不漂亮或看起来像pythonic。

import multiprocessing
from functools import partial


def f(s1, s2, i):
    return [s1] + [s2]*i

def wrapper(i, s1, s2):
    return f(s1, s2, i)

def main():
    # other code... constants for f aren't known until runtime
    pool = multiprocessing.Pool()
    func = partial(wrapper, s1='foo', s2='bar')
    for strings in pool.map(func, range(10)):
        print(strings)
    pool.close()
    pool.join()

if __name__ == '__main__':
    main()
4

1 回答 1

1

顺序很重要,因为pool.map正在调用f(i, s1='a', s2='c')。你可以这样写你的部分:

import multiprocessing

def f(s1, s2, i):
    return [s1] + [s2]*i

def f2(i):
    return f('a','c',i)

if __name__ == '__main__':
    pool = multiprocessing.Pool()
    for strings in pool.map(f2, range(10)):
        print(strings)
    pool.close()
    pool.join()

如果您使用的是 python3.3,您可以使用pool.starmap

import multiprocessing
from itertools import repeat

def f(s1, s2, i):
    return [s1] + [s2]*i

if __name__ == '__main__':
    pool = multiprocessing.Pool()
    for strings in pool.starmap(f, zip(repeat('a'), repeat('c'), range(10))):
        print(strings)
    pool.close()
    pool.join()
于 2016-01-23T00:51:08.577 回答