高階関数というのはWikipediaから引用すると以下のようなものらしいです
高階関数とは第一級関数をサポートしているプログラミング言語において少なくとも以下のうち1つを満たす関数である
・関数を引数に取る
Wikipedia – 高階関数
・関数を返す
つまり関数を引数に取るか、関数を返す関数のことなんですね
簡単な高階関数を実装してみる
試しにとても簡単な高階関数を作ってみましょう
このコードは
関数を受け取って実行する関数であるdo_function
を使ってsay_hello
を実行しています
def do_function(func):
func()
def say_hello():
print('hello')
do_function(say_hello)
# hello
確かに高階関数の定義である”関数を引数に取る” を満たしているので、do_function
は高階関数になっていますよね
Pythonでよく使う高階関数
map
map
は第一引数に関数、第二引数にはイテラブル(リスト, タプル)を与えると
イテラブルの全ての要素に第一引数の関数を適用した値を返すイテレータを返してくれます
またabs
は絶対値を返してくれる関数でこれも組み込み関数です
x = [ i for i in range(-5, 6)]
# [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
for i in map(abs, x):
print(i)
# 5
# 4
# 3
# 2
# 1
# 0
# 1
# 2
# 3
# 4
# 5
filter
filter
は第一引数に関数、第二引数にイテラブル(リスト、タプル)を取り、イテラブルの要素に関数を適用した結果がTrue
であれば、その要素を抽出します
実際に返すものはfilterオブジェクトですが、イテレータと同じように中身を取り出すことが可能です
x = [ i for i in range(-5, 6)]
# [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
def isPositive(a):
if a > 0:
return True
else:
return False
for i in filter(isPositive, x):
print(i)
# 1
# 2
# 3
# 4
# 5
reduce
reduceは要素を足していったり、かけていったりすることで、一つの値にしてくれます
reduce
も第一引数に関数、第二引数にイテラブルを取りますが、前述のmap, filter
と違い、関数は2つを引数に取るようなものである必要があります
例えばreduce
を用いて総和を求めるならこんな感じになりますね
from functools import reduce
def add(a, b):
return a+b
x = [ i for i in range(0,10)]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(reduce(add, x))
# 45
max
max
は最大値を返す関数ですが、key
に関数を渡すことで、その関数を適用後の値に対してmax
を適用します
あくまで適用後の値を基準にして最大値を見つけるだけであり、実際に返ってくるのは与えた要素のうちの一つです
x = [ i for i in range(-6, 6)]
# [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
print(max(x))
# 5
print(max(x, key=abs))
# -6
sorted
sortedはソートしたリストを返すものですが、keyに関数を渡すことで、関数を適用した値を基準にしてソートしてくれます
あくまで適用後の値を基準にしてソートするだけであり、実際に返ってくるのは与えたリストが並べ替えられたものです
x = [ i for i in range(-6, 6)]
# [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
print(sorted(x))
# [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
print(sorted(x, key=abs))
# [0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6]
lamdaを使ってスッキリ
高階関数に渡す関数は簡単なものが多いですが、とても簡単な関数をいちいち定義するのは面倒ですよね?
そこでlambda式(無名関数)を使えばスッキリさせることができるのです
lambdaはこんな感じで使います
lambda 引数: 返り値
lambda x, y: x+y # 足し算
lambda x: x**2 # 二乗
それではlamdaを用いて高階関数をお手軽に使ってみましょう
x = [ i for i in range(0, 10)]
print(list(map(lambda n: n**2, x)))
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
いかがでしょうか?
二乗するための関数をわざわざ定義する必要もなく、コードもスッキリしました
コメント