Irohabook
0
1057

Pythonの高階関数reduceの使い方:gcdを使って3つ以上の最大公約数を求めてみよう

Python のリストから別の値を出したいとき、 reduce という関数が便利である。例を見てみよう。

from functools import reduce


def add(x, y):
    return x + y


a = [2, 3, 7, 1]
b = reduce(add, a)

print(b)
# 13

reduce を使うには functools から reduce をインポートする必要がある。

reduce に関数とリストを入れている。関数 add は 2 つの引数を足すという単純なもの。ここで reduce は次のことをしている。

  1. a から最初の 2 つを取りだす
  2. それを add する
  3. その値と a の次の要素を add する
  4. その値と a の次の要素を add する
  5. 以下くりかえし…

つまり reduce は

add(2, 3) = 5
add(5, 7) = 12
add(12, 1) = 13

の順に処理している。

Python の reduce に入れるリストは、実は 1 個でもエラーが出ない

Python の reduce は最初にリストの 2 つの要素を必要とする(必要としているように見える)が、次のコードはエラーでない。

from functools import reduce


def add(x, y):
    return x + y


a = [2]
b = reduce(add, a)

print(b)
# 2

不思議なことに 2 が返る。

ではリストでなく値を渡したらどうなるか?

from functools import reduce


def add(x, y):
    return x + y


a = 2
b = reduce(add, a)

print(b)

これはエラーになる。

Python の reduce で最大公約数を求める

Python にはデフォルトで最大公約数を求める gcd という関数がある。これは Python の math というライブラリからインポートする。

from functools import reduce
from math import gcd

a = [12, 18, 24]
b = reduce(gcd, a)

print(b)
# 6

gcd は 2 つの数の最大公約数を求める関数で、複数の値に対応していない

math.gcd(a, b)
Return the greatest common divisor of the integers a and b. If either a or b is nonzero, then the value of gcd(a, b) is the largest positive integer that divides both a and b. gcd(0, 0) returns 0.
New in version 3.5.
math — Mathematical functions

つまり 3 つ以上の数から最大公約数を求めるときは、自分でループ処理をしないといけない。しかし Python の reduce を知っていれば、たった 1 行のコードですむ。

Python の reduce を使う場面がわかってきたと思う。これは 2 つの値を使って別の値を求めるような関数を、そのままリストに適用したいときに使うのだ。

もう少し慎重に説明すると、適用したい関数は引数と返す値が同じようなものでないといけない。つまり 2 つの引数は数値だが、返す値は bool や文字列ということはありえない。

次の記事

リスト・辞書