【python】reduce関数を徹底解説

python

pythonのreduce関数を使いこなしたい人

pythonのreduce関数を使いこなしたい人
「pythonのreduce関数を使うと、色々な処理を1行で行えてしまうらしいんですが本当ですか?そもそもreduce関数というのはどのような処理をする関数なのでしょうか?あと、コピペ可能なサンプルコードをください」

こんな悩みを解決します。

本記事の内容

  • 1.reduce関数とは?
  • 2.reduce関数には制約がある(初期値なしで使う場合)
  • 3.reduce関数の初期値設定
  • 4.reduce関数を用いたワンライナーの例

この記事を書いている私はIT業界歴12年、年収1,000万円ちょっとの金融系エンジニアです。学生時代から様々なプログラミング言語を扱ってきましたが、その中でもpythonはとても扱いやすく生産性も高く、オススメの言語です。

本記事では、pythonでreduce関数の使い方とワンライナー(1行プログラム)について解説します。具体例を示し、細かい構文に迷ったときにコピー&ペーストして使えることも目指しました。少しでもお役に立てますと幸いです。

reduce関数とは?

reduce関数とは

reduce関数は、引数に指定したlistの各要素に対して次々と指定した関数を適用する関数です。関数を引数に取るため、「関数の関数」という意味から高階関数とも呼ばれます。

構文①(初期値なしで使う場合)

reduce(《関数(func)》,《list》)

《関数》をfunc、《list》を[s1, s2, s3, s4]としてreduce関数がどのような処理をするのかイメージしたのが下図です。
reduce関数の処理イメージ①

簡単な例

>>> import functools
 
>>> lst=[1,2,3,4,5]
>>> functools.reduce(lambda a,b:a+b,lst)
15
 

関数(func)はlambda a,b:a+b、listは[1,2,3,4,5]ですから計算式は以下の通りです。

 
reduce(rambda a,b:a+b,[1,2,3,4,5])
=func(func(func(func(1,2),3),4),5)
=func(func(func(1+2,3),4),5)
=func(func(1+2+3,4),5)
=func(1+2+3+4,5)
=1+2+3+4+5
=15
 

reduce関数には制約がある(初期値なしで使う場合)

reduce関数には制約がある

先ほどの例では、中から順番に以下の4つの計算をしています。

 
1つ目の計算:func(1,2)=3
2つ目の計算:func(3,3)=6
3つ目の計算:func(6,4)=10
4つ目の計算:func(7,5)=15
 
  • 第一引数と第二引数はリストの各要素です。
  • 途中の計算結果(1つ目〜3つ目の計算)が、次の計算(2つ目〜4つ目の計算)の第一引数になります。

この2点より、reduce関数では次の制約が生じます。

計算結果(上例:15)は、計算元(上例:[1,2,3,4,5])の各要素(上例:1〜5)と同じ型(上例:整数型)でなくてはならない

型に依存しない関数を用いればこの制約は生じませんが、これは結構厄介な制約です。しかし初期値を設定することで、この制約を回避できます。

reduce関数の初期値設定

reduce関数の初期値設定

構文②(初期値を設定する場合)

reduce(《関数》,《list》,《init》)

reduce関数の処理イメージ②

簡単な例

初期値を使った簡単なreduce関数の例を示します。listの各要素(整数型)を文字列として繋げていく(文字列型)だけのコードです。

>>> import functools
 
>>> lst=[1,2,3,4,5]
>>> functools.reduce(lambda a,b:a+str(b),lst,"")
'12345'
 

初期値に空文字列を指定することで、第一引数と実行結果は必ず文字列型になります。これにより、listの各要素(整数型)と実行結果く(文字列型)の型が違っていてもうまく機能するようになりました。

初期値なしで実行してみると、やはり第一引数の型が合わずにエラーとなってしまいます。

 
>>> functools.reduce(lambda a,b:a+str(b),lst)
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 1, in 
TypeError: unsupported operand type(s) for +: 'int' and 'str'
 

reduce関数を用いたワンライナーの例

reduce関数を用いたワンライナーの例

ここまでの内容を踏まえ、いくつかのワンライナーの例を紹介します。

順番に足す(listでΣシグマの計算)

>>> from functools import reduce
 
>>> lst=[10,2,3,4,5]  
>>> //1行のプログラムで順番に足していく(10,10+2,10+2+3,10+2+3+4,10+2+3+4+5)
>>> reduce(lambda making,x:making+[making[-1]+x], lst[1:], [lst[0]])
[10, 12, 15, 19, 24]
 

順番に掛ける(listで!階乗の計算)

>>> from functools import reduce
 
>>> lst=[10,2,3,4,5]  
>>> //1行のプログラムで順番に掛けていく(10,10*2,10*2*3,10*2*3*4,10*2*3*4*5)
>>> reduce(lambda making,x:making+[making[-1]*x], lst[1:], [lst[0]])
[1, 2, 6, 24, 120]
 

計算と型変換を行う

>>> import functools
 
>>> lst=[1,2,3,4,5]
>>> functools.reduce(lambda making,x:making|{x+100}, lst,set())
{101, 102, 103, 104, 105}
 

listの順に文字列を徐々に足していく

>>> import functools
 
>>> lst=['cookie','chocolate','ice cream']
>>> reduce(lambda making,x:making+[making[-1]+" "+x], lst[1:], [lst[0]])
['cookie', 'cookie chocolate', 'cookie chocolate ice cream']
 

 

今回は以上です。reduce関数の使い方とワンライナーの例を解説しました。reduce関数をはじめとする高階関数を使いこなすと、プログラミングスタイルに絶大な影響を及ぼします。

マスターすることで、for文やwhile文による複雑な処理から解放sれ、シンプルでバグの少ないコーディングができるようになるはずです。プログラミングする際の参考になりますと幸いです。

pythonは自動車、半導体メーカーなどでも使われています