高階関数とは
高階関数(higher-order function)とは、関数を引数として受け取ったり、関数を返したりする関数のことです。Pythonでは関数もオブジェクトとして扱えます。
python
# 関数を変数に代入def square(x): return x ** 2f = square # 関数自体を代入(呼び出しではない)f(5) # 25# 関数をリストに入れるfuncs = [square, abs, len]funcs[0](3) # 9lambda式
lambda式は、名前を持たない匿名関数を一行で定義する方法です。
python
# lambda 引数: 式square = lambda x: x ** 2add = lambda x, y: x + ygreet = lambda name: f"こんにちは、{name}!"square(5) # 25add(3, 4) # 7greet("太郎") # "こんにちは、太郎!"注意: lambda式は単純な式のみ記述できます。複雑な処理には通常の
defを使いましょう。
map 関数
map(f, iterable) は、イテラブルの各要素に関数 f を適用します。
python
nums = [1, 2, 3, 4, 5]# lambda を使った mapsquares = list(map(lambda x: x ** 2, nums))squares # [1, 4, 9, 16, 25]# 関数を渡すdef double(x): return x * 2doubled = list(map(double, nums))doubled # [2, 4, 6, 8, 10]# 複数のリストに適用list(map(lambda x, y: x + y, [1, 2, 3], [10, 20, 30])) # [11, 22, 33]filter 関数
filter(f, iterable) は、条件 f を満たす要素だけを取り出します。
python
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]# 偶数だけを抽出evens = list(filter(lambda x: x % 2 == 0, nums))evens # [2, 4, 6, 8, 10]# 正の数だけを抽出data = [-3, 1, -2, 4, -1, 5, 0]positives = list(filter(lambda x: x > 0, data))positives # [1, 4, 5]functools.reduce
reduce(f, iterable) は、リストの要素を順に関数 f で畳み込みます。
python
from functools import reduce# 全要素の積(1 * 2 * 3 * 4 * 5)nums = [1, 2, 3, 4, 5]product = reduce(lambda x, y: x * y, nums)product # 120# 最大値を求めるdata = [3, 1, 4, 1, 5, 9, 2, 6]maximum = reduce(lambda x, y: x if x > y else y, data)maximum # 9関数を引数に取る関数
python
def apply_twice(f, x): """f を x に2回適用する""" return f(f(x))apply_twice(lambda x: x + 1, 5) # 7apply_twice(lambda x: x * 2, 3) # 12sorted の key 引数
sorted() の key 引数に関数を指定すると、ソートの基準を変えられます。
python
words = ["banana", "apple", "cherry", "date"]# 文字列の長さでソートsorted(words, key=len)# ["date", "apple", "banana", "cherry"]# 大文字・小文字を区別しないソートwords2 = ["Banana", "apple", "Cherry"]sorted(words2, key=str.lower)# ["apple", "Banana", "Cherry"]# 複数のキーでソートdata = [(2, "b"), (1, "c"), (1, "a"), (2, "a")]sorted(data, key=lambda x: (x[0], x[1]))# [(1, "a"), (1, "c"), (2, "a"), (2, "b")]デコレータ
デコレータは、既存の関数に機能を追加する特殊な高階関数です。
python
def timer(f): """関数の実行時間を計測するデコレータ""" import time def wrapper(*args, **kwargs): start = time.time() result = f(*args, **kwargs) elapsed = time.time() - start print(f"{f.__name__} が {elapsed:.4f}秒 で完了") return result return wrapper@timerdef slow_function(n): total = 0 for i in range(n): total += i return totalslow_function(1000000) # slow_function が 0.0xxx秒 で完了練習: カスタムソート
学生のリスト(辞書)を点数の降順でソートしてください。
練習: 高階関数の実装
functools.reduce を使わずに、リストの全要素を関数で折りたたむ my_reduce(f, lst, initial) を実装してください。