lambda式(無名関数)
コードの中で変数を使った簡単な定型処理をしたいけれど、関数として定義しておくほど大したものではなく(他のコードで再利用する予定もなく)、そのコードで使い捨てするような関数があれば便利です。Python の lambd式 (ラムダ式) がまさにそうした機能をもつ簡易関数です。lambd 式は基本的に
lambda 引数 : 式
という形で定義します (引数なしで定義することもできます)。lambda 式は名前をつけずに関数を宣言するので、無名関数 (匿名関数)とよばれることもあります。
lambda 式の基本的な使い方
まずは lambda 式を使った簡単なコードを書いてみます。
# PYTHON_LAMBDA
# In[1]
# f(x) = |x|+2x
func = (lambda x : abs(x) + 2*x)
a = func(-1)
b = func(0)
c = func(1)
print("a =", a)
print("b =", b)
print("c =", c)
# a = -1
# b = 0
# c = 3
このサンプルコードでは lambda 式を使って |x| + 2x という関数を定義しています。
同じ処理を通常の def 構文を使って書くと次のようになります。
# In[2]
# f(x) = |x| + 2x
def func(x):
return abs(x) + 2*x
a = func(-1)
b = func(0)
c = func(1)
print("a =", a)
print("b =", b)
print("c =", c)
# a = -1
# b = 0
# c = 3
このように、def文を使うと改行とインデントが入るので、簡単な関数を定義する場合でも最低 2 行のコードが必要になりますが、lambda 式を使えば 1 行で記述することができます。
lambda 式と条件分枝
上の例では、どちらのスタイルで書いてもたった 1 行しか変わらないので lambda 式の有難味がよくわからないかもしれません。もう少し複雑なコードで比較してみましょう。数学の絶対値の問題でよく出てくるような「変数 x が負のときは |x|, 正のときは x を返す関数」です。まずは def文を使ったコードです。
# In[3]
def func(x):
if x < 0:
return abs(x)
else:
return x
a = func(-5)
b = func(5)
print("a =", a)
print("b =", b)
# a = 5
# b = 5
def文の中に if を使った条件分枝が入るので、関数を定義するために 5 行のコードが必要です。lambda 式を使うと 1 行で済みます:
# In[4]
func = (lambda x : abs(x) if x < 0 else x)
a = func(-5)
b = func(5)
print("a =", a)
print("b =", b)
# a = 5
# b = 5
このように、lambda 式の中に条件分枝を含む処理を書き込むこともできます。やろうと思えば、もっと複雑な処理を 1 行の中に押し込むこともできますが、そうすると可読性が落ちてしまうので、ほどほどにしておいたほうがいいようです。
lambda式によるソート
リストの並び替えの記事でも扱いましたが、sort()メソッドの引数に lambda 式を渡してリストの要素を並び替えることができます。たとえば、整数のペア (a, b) を要素にもつリストがあって、a の値について昇順(小さい順)に並び替えたいときには、次のようなコードを書きます。
# In[5]
# タプルを要素にもつリストを定義
my_list = [(7,5), (2, 4), (9, 0), (8, 8)]
# インデックス0の要素をキーとして昇順に並び替え
my_list.sort(key = lambda x : x[0])
print(my_list)
# [(2, 4), (7, 5), (8, 8), (9, 0)]
コメントを書く