無名関数: ラムダ式

ラムダ式(lambda)を用いて名前のない関数を書けます。名前のない関数を 無名関数 と呼びます。名前が必要ない小さな関数を作るための機能です。

ラムダ式は以下のように書きます。引数と処理をコロン(:)で区切って書きます。引数が複数ある場合は、通常の関数と同じように感まで区切ります。

lambda [引数] : [処理]

以下の例は同じ処理を行っています。

通常の関数:

def add(a, b):
    return a + b

c = add(1, 2)
print(c)
# 3

無名関数:

add = lambda a, b: a + b
c = add(1, 2)
print(c)
# 3

コロンの前のa, bの部分が引数、 a + bの部分が処理です。処理結果が変数addに代入されます。

ここまでの例では普通の関数との違いが分かりづらいです。 具体的にラムダ式が必要となるケースを見てみましょう。

Pythonでは関数の引数に関数を受け取ることができます。たとえばリストを並び替える sorted() 関数は並び順を指定する key 引数 に関数を受け取ることができます。

以下は、 sorted() 関数のシンプルな使い方です。リストの数値を並び替えています。

リストの並べ替え:

sample_list = [19, 14, 10, 15, 20]
a = sorted(sample_list)
print(a)
# [10, 14, 15, 19, 20]

sorted() 関数には key という並び順を指定する引数があり、関数を受け取ることができます。 ここでlambda式の無名関数を利用できます。

上記のリストを 7で割った場合に余りが大きい順 に並び替えてみましょう。

リストを逆順で並べ替え:

sample_list = [19, 14, 10, 15, 20]
a = sorted(sample_list, key=lambda x: x%7)
print(a)
# [14, 15, 10, 19, 20]

key=lambda x: x%7 は、以下と同じ動きをします。

def mod_7(x):
    return x % 7

リストsample_listの要素を並び替える場合に、その要素自体を並び替えずに、その要素に紐付いた key に指定された値で並び替えます。

  • 19 の場合は 19%7 の結果なので、 5
  • 14 の場合は 14%7 の結果なので、 0
  • 10 の場合は 10%7 の結果なので、 3
  • 15 の場合は 15%7 の結果なので、 1
  • 20 の場合は 20%7 の結果なので、 6

このため、7で割った余りをkeyに指定して並び替えると、14, 15, 10, 19, 20の順番となります。

次に辞書を並べ替えましょう。sorted(sample_dict) と指定すると、並び替えられたキーのリストが結果として表示されます。 キーと値のセットで並び替えるには 辞書.items() を利用し、タプルのリストの形にして並び替えます。

辞書をキーで並べ替え:

sample_dict = {'a': 2, 'c': 3, 'b':1}
b = sorted(sample_dict.items())
print(b)
# [('a', 2), ('b', 1), ('c', 3)]

key引数を指定しないとタプルの値で並び替えます。

2番目以降の値で並べ替えをしたい場合は、key引数を利用します。

sample_dict = {'a': 2, 'c': 3, 'b':1}
c = sorted(sample_dict.items(), key=lambda x:x[1])
print(c)
# [('b', 1), ('a', 2), ('c', 3)]

lambda x:x[1] 部分の引数xには、各タプルが渡され、結果として2番目の値x[1]が並び替えのキーとなります。

また、リストのリストも並べ替えられます。

以下の例は3番目の値で並び替えています。

sample_list_list = [[2, 4, 3], [1, 1, 1], [5, 4, 2]]
d = sorted(sample_list_list, key=lambda x: x[2])
print(d)
# [[1, 1, 1], [5, 4, 2], [2, 4, 3]]

key引数にラムダ式を指定することにより、各要素のどの値をキーにするか指定できます。

まとめ

  • ラムダ式を使うと無名関数を作れます。
  • 関数を定義するまでもない小さな処理を関数化したい時に使いましょう。
  • sorted() 関数のkey引数のように、関数を受け取る引数などに使うと良いでしょう。

sorted() 関数について詳しくは、ソート HOW TOを参照ください。

ラムダ式について詳しくは、小さな関数とラムダ式を参照ください。