Pythonのラムダ式(無名関数)とは?
現在、エンジニアがよく使用するプログラミング言語といえば「Python」を思い浮かべる人は多いのではないでしょうか。実際、Pythonはその多様性と強力な機能によって、Web開発からデータサイエンス、人工知能(AI)まで幅広い領域で使われています。
Pythonはコードが読みやすく、比較的短い行数で多くの処理を実現する高水準のプログラミング言語です。そのコード記述をより簡潔にする方法として、多くのエンジニアが重宝しているのが「ラムダ式(無名関数)」です。
ラムダ式を使いこなせるようになると、エンジニアとしてのスキルレベルをさらに向上できると言えます。今回は、Pythonにおけるラムダ式の特徴や使い方、メリット・デメリットなどを解説していきます。
そもそも「ラムダ式(無名関数)」とは何か
Pythonにおけるラムダ式(Lambda expressions)とは「無名関数を作成するための構文」です。無名関数とは「小規模な名前のない関数」のことで「匿名関数」と呼ばれることもあります。
小規模というのは、関数本体には式を1つしか記述できないことを意味します。名前がなくても、ラムダ式を変数や関数やメソッドのパラメーターに設定することで、「名前(引数)」と同じように無名関数を呼び出すことができるのです。
Pythonによる関数の定義・実行について
関数とは、ある特定のタスクや計算を実行する一連の命令をまとめたものです。必要な時に何度でも呼び出すことができるため、同じコードを何度も書くことなく、1度定義した関数を何度でも再利用できます。
こうした再利用性は、コードの効率性と可読性を大いに向上させることに役立ちます。また、関数宣言(定義)と関数呼び出し(実行)を1つの式で処理できる関数式を「即時関数」と呼ぶこともあります。
無名関数はどう使える?
無名関数は、関数を一時的に作成する場合や関数を引数として渡す場合などに用いると大変便利です。たとえば、関数の名前をつける必要がない1行で終わるような関数を作る場合に利用できます。
Pythonプログラミングを学び始めたばかりの時期は、無名関数を用いることはほとんどありません。ただ、Pythonを使う機会がある程度増えたり、業務におけるデータの前処理などで活用したりすることは徐々に多くなります。
ラムダ式では何ができる?
ラムダ式は単体で使うのではなく、他の関数と組み合わせて使うことが前提です。ラムダ式では関数オブジェクトとして扱われます。Pythonでは関数がそのパラメーターに関数オブジェクトを受け取ったり、関数を戻り値として返送したりします。
Pythonでは関数がそのパラメーターに関数オブジェクトを受け取ったり、関数を戻り値として返送したりします。このような部分でラムダ式を使うと便利です。
たとえば、変数に代入したり、他の関数に引数として渡したりすることが可能です。また、一時的な関数として使われるため、名前を付けずに簡潔に関数を表現できます。
ラムダ式の特徴・使い方
ラムダ式を使うことで、Pythonにおける関数の定義を簡潔に表現できます。たとえば、処理内容が少ない関数を実装したい場合、変数に直接戻り値を返したい場合などに使用されます。
通常の関数表現として、Pythonでは「def」を使います。ここからは、ラムダ式とdefとの違いについて解説します。
def文とは?
Pythonで関数を定義する場合、「def」というキーワードを使用します。その後に関数名と引数を記述することで、何度も繰り返す必要があるような処理を部品化したり、再利用することができます。
def 関数名(引数1, 引数2, ..., 引数n):
# ここに実行したい処理を記述する
# 'return'を使って、関数の戻り値を指定
return 戻り値
「関数名」は関数の名前を、「(引数1,引数2, ..., 引数n)」部分には関数に渡すパラメータ(任意)を表します。パラメーターはカッコ内にカンマ区切りで複数指定することが可能です。
そして、関数定義の最初の行に「コロン(:)」を記述します。その次の行から関数の本体となる具体的な処理を記述し、returnを用いて関数の結果(戻り値)を返します。
関数命名のルール
また、Pythonの関数を命名する際には、以下のルールを順守する必要があります。
・関数名は、英字(a-z、A-Z)かアンダースコア(_)で開始する ・関数名には英字、数字、アンダースコアを含むことができるが、特殊文字(「!」「@」「#」「$」等)は許可されていない
ラムダ式での関数の定義方法
ラムダ式では「lambda」というキーワードを使用します。先ほど説明したように、def文では「func」などの関数名が必要です。
一方、lambdaの場合、無名関数の名の通りに関数名を表記する必要がありません。関数名がないので変数に直接戻り値を返す際に使用されます。
【参考】:Python チュートリアル
defとlambdaの違い
defとlambdaの違いは、defが「宣言文」であるのに対して、lambdaは「式」という点です。defを使う場合は事前に宣言が必要ですが、lambdaは式であるためそのまま簡潔に表現できます。また、構文の性質上単一の式に制限されています。
簡単な関数であれば、lambdaでの記述の方がより簡潔に記述できます。ラムダ式の関数は、関数オブジェクトが要求されている場所にどこでも使うことが可能です。
コーディング規約のエラー
Pythonコーディング規約である「PEP8」では、ラムダ式には名前を付けないことを推奨しています。実際、ラムダ式を変数に代入すると、自動チェックツールなどで「Warning」が出ることがあります。その場合でも、あくまでコーディング規約PEP8の推奨となるため、Pythonの文法的にはエラーではなく実行可能です。
Do not assign a lambda expression, use a def (E731)
【参考】:Python コーディング規約PEP8
ラムダ式による簡単なdefの書き換え方
ラムダ式によって具体的にどれくらい簡素化できるのでしょうか。ここでは、以下のような「def」による関数の記述を「lambda」で書き換える方法を見ていきましょう。
・def による関数の記述
def 関数名(引数1, 引数2, …):
# a = 引数を用いた処理
return a
このような一般的な関数を定義する際、lambdaを用いると1行で書き換えることができます。
・lambda による関数の記述
lambda 引数1, 引数2, …: 引数を用いた処理
returnする変数を計算する式を「:」の後ろに持ってくるだけで済みます。
ラムダ式の具体的な利用シーン
続いて、ラムダ式がどのように使われているのか、より具体的な利用シーンを解説していきます。
ラムダ式は、主に「filter関数」「map関数」「sorted(sort)関数」「max(min)関数」「optuna」などの最適化ライブラリと一緒に使われることが多いです。
これらの関数は、引数に対して関数を渡します。その際、ラムダ式を使うことでより簡潔に表現することができるのです。
filter関数との組み合わせ
ここでは、filter関数との組み合わせ例を紹介します。filter関数は、条件に合致するものを抽出する関数です。
・filter関数の記述例
filter(関数,リストなどのオブジェクト)
上記の場合、第一引数に「lambda」を記述します。たとえば、数値リストの中で、ある数値よりも大きい数値を抽出する処理などで活用されます。
map関数との組み合わせ
続いて、map関数との組み合わせ例を紹介します。map関数は、リストなどの複数要素を持つデータに対して、その要素に同じ処理を行う関数です。map関数は以下のように記述します。
・map関数の記述例
map(関数,リストなどのオブジェクト)
上記の場合、第一引数に「lambda」を記述します。たとえば、苗字が羅列されたリストに対して、map関数の第一引数に「さん」を付与する関数を、第二引数に第一引数へ渡すリストを指定することで、リスト内の全ての苗字に「さん」を付与するという処理が簡潔に記述できます。
ラムダ式とif文の組み合わせ
ラムダ式では、簡単な条件分岐の処理を簡潔に記述できますが、複数行にまたがる文を使うことはできません。ただ、「A if B else C」のような3つの項(被演算子)を用いて1つの結果を得る三項演算子に使用することは可能です。
def文、内包表記との使い分け
ここまで説明したように、任意の関数を指定したい場合は、def文で関数を定義するよりもラムダ式で無名関数を指定したほうが簡潔に記述できます。
また、filter関数やmap関数と同様の処理は「リスト内包表記」や「ジェネレータ式(ジェネレータ内包表記)」でも記述可能です。リスト内包表記とは、既存のリストから新しいリストを作ることができる方法の1つです。
ラムダ式は、def文で記述するほどでもない簡単な処理に利用されることが多いです。もちろん、状況に応じて使い分けすることでさらにコーディングを楽にしてくれる存在だと言えます。
apply関数との組み合わせ
Pythonの関数の中で、map関数と類似した処理が可能な関数が「apply関数」です。apply関数とラムダ式、さらにif文を組み合わせることで条件分岐した上でデータを置換することも可能です。
たとえば、データ分析の前処理など特定の条件の文字列や数値を一括返還する際などに便利です。
sorted(sort)、max(min)との組み合わせ
その他、ラムダ式はリストをソートする「sorted関数」やリストの「sortメソッド」、最大値や最小値を返す「max関数」や「min関数」と組み合わせることが可能です。
たとえば、文字列をアルファベット順にソートしたり、最大値・最小値を算出・比較する際などにも活用できます。
リスト内包表記との使い分け
また、filter関数やmap関数と同様の処理は「リスト内包表記」や「ジェネレータ式(ジェネレータ内包表記)」でも記述可能です。
リスト内包表記とは、既存のリストから新しいリストを作ることができる方法の1つです。また、ジェネレータ内包表記とは、作業メモリを節約してプログラムの実行処理速度を高速化させる機能です。簡潔なコードで記述でき、膨大な数の演算処理に適しています。
def文との使い分け
ここまで説明したように、任意の関数を指定したい場合は、def文で関数を定義するよりもラムダ式で無名関数を指定したほうが簡潔に記述できます。
ラムダ式は、def文で記述するほどでもない簡単な処理に利用されることが多いです。もちろん、状況に応じて使い分けすることでさらにコーディングを楽にしてくれる存在だと言えます。
ただし、様々な使用箇所で共通的に使用したい処理の場合、通常のdefを用いた関数を活用することをお勧めします。また、使用範囲が限られる処理内容については、ラムダ式を用いて簡潔に読みやすいコードを記述することを優先する方が望ましいでしょう。
ラムダ式は、Pythonエンジニアとしてのスキル向上に役立つ
ラムダ式は、無名関数(匿名関数)を簡潔に記述するための構文です。通常の関数定義に比べて、一時的な関数の場合や短い処理の場合にすばやく関数を作成できます。また、コードの簡潔さによって可読性を向上することも可能です。
特に、リストや辞書などのデータ構造を操作するようなデータの変換やフィルタリングなどに非常に便利です。ラムダ式を使いこなすことで、よりエンジニアとしてのスキルアップを図ることをおすすめします。
編集部オススメコンテンツ
アンドエンジニアへの取材依頼、情報提供などはこちらから