6-2

高階関数

高階関数:関数を引数に渡すデータ[1,2,3,4,5]map(f, list)各要素にfを適用f = lambda x: x**2結果[1,4,9,16,25]

高階関数とは

高階関数(higher-order function)とは、関数を引数として受け取ったり、関数を返したりする関数のことです。Pythonでは関数もオブジェクトとして扱えます。

python
# 関数を変数に代入def square(x):    return x ** 2f = square       # 関数自体を代入(呼び出しではない)f(5)   # 25# 関数をリストに入れるfuncs = [square, abs, len]funcs[0](3)   # 9

lambda式

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)   # 12

sorted の 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) を実装してください。