lambda(ラムダ)式は、「無名関数」という名前のない関数を作るための式です。
しかし、通常、関数を作るにはdef文があるため、lambdaが何のためにあるのか分からないという方も多いでしょう。
結論から言うと、lambdaは、sorted()関数やmap()関数、filter()関数など、引数に関数を受け取る関数を使うときに、簡潔なコードを書くために使います。
これについて詳しく解説していきます。
1. lambda(ラムダ)とは
lambda(ラムダ)は、「無名関数」と呼ばれます。その名の通り、関数名をつけずに、簡潔に関数を作成するために使う構文です。
lambdaの基本書式は次の通りです。
lambda 引数1, 引数2, ..., 引数n : 式
このように、lambdaと書いて、「これからlambda式を書きますよ」とPythonに宣言してから、その右側にまず引数を書き、コロン( : )で区切ってから、関数定義の処理文を書きます。
通常、独自関数を作成するにはdef文を使います。見比べるために、次のコードでは、引数に渡した数値を二乗するsquare()関数をdef文で作っています。
''' def文で関数を作ります。 '''
def square(n):
return n**2
''' 関数を実行します。 '''
square(3)
これと同じものをlambdaで書くと、次のようになります。
''' lambda式で同じ関数を作ります。 '''
square = lambda n : n**2
''' 関数を実行します。 '''
square(3)
簡単ですね。
なお、このコードでは、lambda式を変数squareに代入しています。lambda式を代入して変数は関数オブジェクトとなり、通常の独自関数として使うことができます。
ただし、PythonのPEP8というコーディングのルールでは、lambdaを変数に代入して使うことは推奨されていません。
2. lambdaはどういう時に使う?
それでは、lambdaはどのような時に使うのでしょうか。
それは関数の引数に関数を渡したい時です。
Pythonにおけるプログラミングの現場で、このような使い方をもっとも目にするのは、sorted()関数、map()関数、filter()関数を使う時です。
それぞれ見ていきましょう。
2.1. sorted()関数とlambda
sorted()関数は、リストなどのイテラブルの要素をソートする関数です。
sorted()関数は、キー引数で関数を渡すと、その関数で定義されているルールの通りに並び替えることができます。
例えば、以下のリストに対して、キー引数を指定せずにsorted()関数にかけると、通常の並び替え法則(内側のタプルの最初の要素を数値昇順)にしたがってソートされます。
list = [(0, 5), (2, 3), (1, 4), (3, 2), (5, 0), (4, 1)]
sorted(list)
この時、もし、通常の並び替え法則の通りではなく、内側のタプルの二番目の要素を数値昇順でソートしたい場合は、キー引数にlambda式を渡すことで実現することができます。
sorted(list, key=lambda x : x[1])
なお、sorted()関数だけでなく、sort()メソッドでも同じようにキー引数を渡すことができます。
2.2. map()関数とlambda
map()関数は、イテラブルの全ての要素に指定の関数を適用して返すものです。
次のように書きます。
map(関数, イテラブル)
これは例えば、既にある数値のリストの各要素を二乗したものが欲しい、だけど、符号はそのままにしておきたい、など少しひねった操作をしたい時に使います。
def文で関数を作ってから、map()関数でイテラブルを操作するとしたら、次のように書きます。if文に関しては「Pythonのif文を使った条件分岐の書き方」をご覧ください。
nums = [0, -1, 2, -3, 4, -5]
def square(n):
if n > 0:
return n**2
else:
return n**2*-1
list(map(square, nums))
これをlambdaで書くと、はるかに簡潔なコードになります。
nums = [0, -1, 2, -3, 4, -5]
list(map(lambda n : n**2 if n>0 else n**2*-1, nums))
このように、lambdaでも三項演算の式を書くことができます。
なお、少しトリッキーですが、次のように書くと、さらに簡潔になります。
nums = [0, -1, 2, -3, 4, -5]
list(map(lambda n : n**2*(1, -1)[n<0], nums))
これは、(1, -1)[n<0] で、n<0の条件式がTrueなら-1を、Falseなら1を掛けるというものになっています。
Pythonではブール値のTrueは1、Falseは0を意味します。このブール判定値によってタプル(1, -1)のどちらかの数値をスライスしているのですね。
print((1, -1)[True])
print((1, -1)[False])
2.3. filter()関数とlambda
filter()関数は、イテラブルから条件に合う要素だけを抜き出す関数です。
書き方はmap()関数と同じで、第一引数に関数、第二引数にイテラブルを渡します。
filter(関数, イテラブル)
例えば、次のようにリストの中から正の数値だけ抜き出したい場合などに使います。
nums = [0, -1, 2, -3, 4, -5]
list(filter(lambda n : n>=0, nums))
3. まとめ
このようにlambda式は、sorted()関数、map()関数、filter()関数を簡潔に書きたい時にとても便利です。
ただし、複雑な処理を書くには向いていません。
lambdaを使うことによって、可読性(第三者から見た時のわかりやすさ)が向上するかどうかを、しっかり考えてから使うようにしましょう。
コメント