partial()関数は、functoolsモジュールの一部です。
高階関数といって、関数に影響を及ぼしたり他の関数を返したりするためのものです。
https://docs.python.jp/3/library/functools.html
同じくfuctoolsの一部のreduce()関数を使いながら、partial()関数を見てみましょう。
reduce()関数についてはこちら
→【Python入門】reduce()を使いシーケンスの個々の要素に同じ関数を適用する,Python3
zip()関数についてはこちら
→【Python入門】zip()を使った複数のシーケンスの反復処理(for文応用),Python3
1 2 3 4 5 6 7 8 9 10 |
>>> from functools import reduce >>> from functools import partial >>> >>> >>> def vector_add(v, w): #たとえばベクトル[1, 2]と[2, 1]の和は[3, 3]となる ... return [v_i + w_i for v_i, w_i in zip(v, w)] #リスト内包表記 ... >>> vector_sum = partial(reduce, vector_add) #ベクトルのリストの要素ごとの和を求める >>> vector_sum([[2,3], [3,4], [5, 6], [8, 9]]) #これは[2+3+5+8, 3+4+6+9] [18, 22] |
1 2 3 4 5 6 7 8 9 10 |
>>> from functools import reduce >>> from functools import partial >>> >>> >>> def vector_add(v, w): ... return [v_i + w_i for v_i, w_i in zip(v, w)] ... >>> vector_sum = partial(reduce, vector_add) >>> vector_sum([[2,3], [3,4], [5, 6], [8, 9]]) [18, 22] |
partial()に関するドキュメントはこちらです
→https://docs.python.jp/3/library/functools.html#functools.partial
引用すると、
言葉で定義すると難しくなりますね。
上の例で言うなら、あるベクトルたちを収納したリストがあり、そのリストの要素の和を求めたいと思ったとします。
要素の和自体はvector_addが操作を担当、リストにあるベクトルの和を求めていき(reduce()関数)、結果をまとめる(partial()関数)。
というようなかたちになっています。
vector_addという関数にreduce()関数を適用した結果、新しいオブジェクトを作り出したのがpartial()関数と言えるでしょう。
関数を単位に考えて、関数を扱う関数が使いこなせるようになると、Pythonプログラミングの幅はぐっと広がります。
おまけ:ベクトルリストの要素の平均
上の例ではベクトルのリストの要素の総和を求めました。
要素の平均なら、
1 2 3 4 5 6 7 8 9 |
>>> def scalar_multiply(c, v): ... return [c * v_i for v_i in v] ... >>> def vector_mean(vectors): ... n = len(vectors) ... return scalar_multiply(1/n, vector_sum(vectors)) #vector_sum()は上記参照 ... >>> vector_mean([[2,3], [3,4], [5, 6], [8, 9]]) [4.5, 5.5] |
vector_sum()によって[18, 22]ができあがり、これは4要素分を足した結果ですよね。
なのでvectorsをlen()して要素数を出していて、その4で割って平均を出しています。