reduce関数 シーケンスの値を累積的に集約する

Python2までは組込みでrudece関数というものがあったのですが、Python3ではfunctoolsという標準モジュールのメソッドとして提供されています。map、filter、zip関数とともによく使用するため、ついでにご紹介します。

reduce関数

reduce関数はリスト等のシーケンスの値を累積的に計算を行い1つの値に集約します。1番目の引数に、引数を2つ持つ関数を、2番目にリスト等のシーケンスを指定します。日本語の説明よりも、最初にサンプルを読んだほうがわかりやすいでしょう。以下は、1〜4までの和を求めるサンプルです。

from functools import reduce

def add(arg1, arg2):
    """ 2つの値を足して返す """
    return arg1 + arg2

x = reduce(add, [1, 2, 3, 4])
print(x) # 10

これはつまり、add(add(add(1, 2), 3), 4) = (((1 + 2) + 3) + 4) = 1 + 2 + 3 + 4 と同じことですね。

累積した前回の値を使用できるため、時系列データ分析の計算でよく使用します。

補足 lambda式と組み合わせる

いつもの流れです。やはり上のような簡単な高階関数を使用する場合はlambdaを使用したほうが良いでしょう。

from functools import reduce

x = reduce(lambda x, y: x + y, [1, 2, 3, 4])
print(x) # 10

いつも通り、ずいぶんスッキリ書くことができました。

補足2 必ずしも両方の引数を使う必要はない

reduceの一番目の引数は、引数を2つもつ関数を指定しますが、前回の値から導出できる場合は2番目の引数を使わない場合もあります。例えば、7%の金利で11年間複利で回した場合の計算は以下のようになります。0年始まりなので、要素数は12を指定しています。

from functools import reduce

def kinri(arg1, arg2):
    return arg1 + arg1 * 0.07

x = reduce(kinri, [100] * 12)
print(x)

7%複利を11年間回すと2倍になることが確認できます。(余談ですが金融業界ではこれをセブンイレブンの法則と呼んでいました。)

少々無理やりな説明でしたが、一部の引数を使わなくて済む場合もある、というわけです。