Pythonインタラクティブガイド - ステップ3 関数 (8) - 高階関数
- 本講座「Pythonインタラクティブガイド」は、手を動かしながらPythonプログラミングの基礎を学べる実践的な講座です。
- 「スタイルガイド」では、Pythonで読みやすくきれいなコードを書くためのガイドライン(PEP8)を主に紹介しています。
- 各コード例はその場で実行して結果を確認できます。
ページ再読み込みで元に戻るので、自由に試してみてください。
「ステップ3 関数」の続きです。
3.7. 高階関数
前回はラムダ式を変数に代入して扱う方法を学びました。Pythonでは通常の関数もオブジェクトとして変数に代入でき、さらに関数を戻り値として返すことも可能です。
関数を入力や出力する関数のことを高階関数 (higher-order function)といいます。
3.7.1. 関数を入力する関数
Pythonでは関数を引数として受け取り、その関数を利用して内部で処理を行う関数を作成できます:
この例では、apply_function
関数が関数 (double
や square
) を引数として受け取り、その関数を内部で呼び出して処理を行っています。
前回学んだラムダ式と組み合わせると、より簡潔に記述できます:
リストと「条件関数」を受け取り、条件を満たす要素だけを抽出する filter_elements
関数を作成しましょう。
条件関数は、要素を受け取ってブール値(True
/False
)を返す関数です。
解答例
3.7.2. 関数を出力する関数 (クロージャ)
Pythonでは、関数を戻り値として返す関数も作成できます:
この例では、make_multiplier
関数は引数 factor
を受け取り、その値を使ってかけ算を行う新しい関数 multiplier
を返します。
例えば、make_multiplier(2)
で生成された関数は、呼び出すと入力値に2
をかけた数値を返します。
このように、make_multiplier
が生成する関数multiplier
は、外に出力された後もエンクロージングスコープの変数factor
の値を「覚えて」います。
このような、出力された後も生成元の関数の情報を保持する内部関数のことを「クロージャ」と呼びます。
別のクロージャの例を見てみましょう:
クロージャの仕組みを利用すると、グローバル変数を使用せずにカウンターを生成する関数を作成することも出来ます:
このように、クロージャの仕組みを利用すると、グローバルスコープを汚さずに「記憶を持つ関数」を作成することができます。
指定された接頭辞を付ける関数を生成する make_prefixer
関数を作成しましょう。
解答例
初期HPを指定すると、そのHPを管理する関数を返す hp_manager
関数を作成しましょう。
返された関数は、ダメージ量を引数として受け取り、そのダメージを受けた後の残りHPを返します。
ただし、HPは0未満になったら0を返してください。
この関数を使って、2種類のモンスターのHPを別々に管理しましょう。
解答例
3.7.3. 組み込み高階関数
Pythonには、高階関数として使用できる便利な組み込み関数がいくつか用意されています。
特に頻繁に使用される関数について見ていきましょう。
map
関数
map
関数は、イテラブル (繰り返し可能なオブジェクト) の各要素に指定した関数を適用し、その結果をイテレータ (iterator) として返します。
- 「イテレータ」はイテラブル(繰り返し可能なオブジェクト)の一種で、一度だけ順に取り出せる「使い切り」のオブジェクトです。
- イテレータを複数回利用したい場合は、
list()
関数などでリストに変換します。 - ジェネレータ式で扱った「ジェネレータ」も、イテレータの一種です。
- ジェネレータと同様に、結果を一度に生成するのではなく、必要に応じて一つずつ値を生成するためメモリ効率が良いです。
- イテレータの詳細は、後ほど解説します。
filter
関数
filter
関数は、イテラブルの各要素に指定した条件関数を適用し、True
を返す要素のみを含むイテレータを返します:
sorted
関数
リストの項で扱ったsorted
関数も、実は高階関数の一種です。
key
パラメータに関数を渡すことで、ソートの基準をカスタマイズできます:
以下のコードを完成させて、指定された出力を得られるようにしましょう:
解答例
まとめ
この節では、Pythonの高階関数について以下のポイントを学びました:
- 高階関数の概念: 関数を入力や出力する関数
- 関数を入力する関数: 他の関数を引数として受け取り、その関数を利用して処理を行う関数の実装方法
- 関数を出力する関数 (クロージャ): 新しい関数を生成して返す関数の作成方法と、生成元の関数の情報を保持するクロージャの仕組み
- 組み込み高階関数: Pythonに標準で備わっている高階関数である
map()
,filter()
,sorted()
の活用方法
高階関数を使いこなすことで、より柔軟で簡潔なコードを書くことができます。
次回は、高階関数の応用例である「デコレータ」について学びます。