functools
前回、itertoolsの無限イテレータcount、cycle、repeatを紹介しました。
今回はfunctoolsのpartialを使って特定の関数の一部の引数を固定した新しい関数を作る方法を紹介します。
関数の一部の引数を固定するということなので、基本となる関数をこんな感じで作成してみました。
def add_calc(a, b, c):
return 1*a + 2*b + 3*c
print(add_calc(1, 2, 3))
実行結果
14
それでは始めていきましょう。
functools.partical
functools.partialは「functools(関数名, 値)」として使用します。
また値は引数の前から当てはめられます。
import functools
def add_calc(a, b, c):
return 1*a + 2*b + 3*c
add_calc_new = functools.partial(add_calc, 100)
print(add_calc_new(1, 2))
実行結果
108
この例では引数aがfunctools.partialで指定した値100となり、二つの引数bとcが残ります。
そのため、functools.partialで新たに作成した関数「add_calc_new」では引数bとcの二つを必要とします。
import functools
def add_calc(a, b, c):
return 1*a + 2*b + 3*c
add_calc_new = functools.partial(add_calc, 100, 1000)
print(add_calc_new(1))
実行結果
2103
こちらの例では引数aとbがそれぞれ100と1000で固定されます。
そして引数cのみが新たな関数「add_calc_new」で必要とされます。
しかしながら固定したい引数が前から存在している場合ばかりではありません。
例えば2番目の引数bを固定したい場合はfunctools.partialの引数に「b=値」を追加します。
また新たな関数の引数でも「a=値」、「c=値」のように引数名を書きます。
import functools
def add_calc(a, b, c):
return 1*a + 2*b + 3*c
add_calc_new = functools.partial(add_calc, b=100)
print(add_calc_new(a=1, c=2))
実行結果
207
ただし固定する関数が最後の場合、そして新しい関数で必要な引数が元の関数での引数で前から並んでいる場合は、新しい引数で引数名は省略できます。
import functools
def add_calc(a, b, c):
return 1*a + 2*b + 3*c
add_calc_new = functools.partial(add_calc, c=5)
print(add_calc_new(1, 2))
実行結果
20
もし引数名が必要にも関わらず、記載しなかった場合はエラーとなります。
import functools
def add_calc(a, b, c):
return 1*a + 2*b + 3*c
add_calc_new = functools.partial(add_calc, b=5)
print(add_calc_new(1, 2))
実行結果
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[14], line 8
4 return 1*a + 2*b + 3*c
6 add_calc_new = functools.partial(add_calc, b=5)
----> 8 print(add_calc_new(1, 2))
TypeError: add_calc() got multiple values for argument 'b'
mapと合わせた使い方
ちなみにfunctools.partialはmap関数で使いたい関数の一部を固定するのに使うと便利です。
import functools
a_list = [1, 2, 3, 4, 5]
def add_calc(a, b, c):
return 1*a + 2*b + 3*c
result_list = map(functools.partial(add_calc, b=100, c=1000), a_list)
print(*result_list)
実行結果
3201 3202 3203 3204 3205
次回はitertoolsでリストの値の累積和を取得する関数accumulateを紹介します。
ではでは今回はこんな感じで。
コメント