3

関数の実行を高速化するためにマルチプロセッシングを使用しようとしてpool.mapいますが、イテラブルはその関数の最初の引数ではありません。ピクル可能ではないため、ラムダは機能しません。functools.partialを使用して新しい関数を作成しようとしましたが、 TypeError. 以下は、同じ結果の非常に単純な例です。引数の順序を に切り替えると、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()

更新:私が考えることができる最善の方法は、モジュールレベルでラッパーを作成して引数の順序を切り替え、次にラッパーから部分的に切り替えることです。きれいに見えないか、まったくパイソンのように見えません。

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 に答える