以前、関数の記事で、def を使って独自の関数を定義する方法を学習しました。関数は「処理のまとまりに名前をつけて、後から何度も呼び出せるようにする」ものでした。今回は「名前のない、その場限りの処理」を一行で書くことができる「lambda(ラムダ)式」について解説します。

lambda式を使用する

Pythonでlambda式を使うには、lambdaというキーワードの後に引数、コロン : 、そして実行したい式(返り値となる式)を記述します。
なので例としてlambda式は、

lambda 引数: 返り値となる式

の形式で記述します。

以前学習した通常の関数作成(def)と比べると、この書き方には大きな違いがあります。具体的には次のような特徴があります。

  1. 名前がない(無名関数): def test(): のように関数の「名前(test)」を付ける手順が省かれています。そのため、lambda式は「無名関数(むめいかんすう)」とも呼ばれます。何度も呼び出すのではなく、「今、ここだけで一回だけ使いたい処理」を作るために最適化されています。
  2. returnを省略できる: def の場合は、計算した結果を呼び出し元に返すためにreturn というキーワードを書く必要がありました。しかし、lambda式ではコロン : の右側に書いた「式」の計算結果が自動的に返される(returnされる)仕組みになっています。
  3. 1行で書く: def を使った関数では複数行にわたって複雑な処理を書くことができますが、lambda式は基本的に1行で完結するシンプルな式(計算など)しか書くことができません。その分、コードを非常にコンパクトにまとめることができます。

では、実際にやってみましょう。
Google Colaboratory (Colab) を開いて新しいノートブックを作成し、まずはdeflambdaの書き方の違いを確認してみましょう。

# [従来の書き方] defを使って足し算の関数を定義する
def add_def(a, b):
  return a + b

print(f"defを使った結果: {add_def(1, 2)}")

# [lambda式の書き方]名前をつけずに1行で処理を書く
# 動作確認のため、「add_lambda」という変数に代入する
add_lambda = lambda a, b: a + b

print(f"lambdaを使った結果: {add_lambda(1, 2)}")

とセルに入力して実行してみましょう。すると結果は

defを使った結果: 3
lambdaを使った結果: 3

のように表示されます。

プログラムの解説(シンプルな足し算)

  • defを使った関数の定義(2~3行目): 通常の書き方です。add_def という名前の関数を作り、引数abを足した結果をreturnで返しています。
  • lambda式を使った関数の作成(9行目): lambda a, b: a + b と記述しています。引数a, bを受け取り、a + b の結果を自動的に返します。通常は変数に代入せずそのまま使い捨てますが、ここでは比較のためにあえて変数add_lambda に格納して使っています。

filter()関数とlist()関数について

lambda式の最も一般的で便利な使い道の一つに、リストの中から「特定の条件を満たすデータだけを抽出する」処理があります。これには、Pythonに最初から用意されているfilter()(フィルター)関数をよく使います。

filter()関数は、括弧の中に「条件を判定する関数」と「リストなどのデータ」をカンマ区切りで渡して使います。リストのデータを1つずつ関数に渡し、結果がTrue(真)になったものだけを残すという便利な機能を持っています。

この「条件を判定する関数」として、その場限りの条件(例えば「偶数ならTrueにする」など)を直接渡すときに、lambda式が非常に役に立ちます。

抽出結果をリストに戻すlist()関数

ここで一つ注意点があります。filter()関数が抽出した結果は、そのままでは中身を直接見ることができない特殊な状態(イテレータ)になっています。そのため、抽出した結果を私たちが普段使っているリストの形に戻すために、list()という関数を使います。list(filter(...))のように、filter全体をlist()で囲むことで、抽出されたデータが綺麗なリストとして表示・保存できるようになります。

filter()関数と組み合わせて使う

次に、先ほど解説した filter() 関数、list()関数とlambda式を組み合わせてみましょう。

# 数字のリストを用意する
numbers = [i for i in range(1, 7)]

# filter()関数を使って、偶数(2で割り切れる数)だけを取り出す
# lambda x: x % 2 == 0 という「その場限りの条件式」を直接渡しています
# その結果を list()で囲んで、リストの形に戻します
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))

print(f"偶数だけを抽出した結果: {even_numbers}")

とセルに入力して実行してみましょう。すると結果は

偶数だけを抽出した結果: [2, 4, 6]

のように表示されます。

プログラムの解説(filter関数)

  • filterとlistの組み合わせ(7行目): list(filter(lambda x: x % 2 == 0, numbers)) と記述しています。
    • filter()関数は、データの中から「条件を満たすものだけ」を抽出します。ここで「条件を満たすかどうかを判定する関数」として、lambda x: x % 2 == 0 (受け取った数が偶数ならTrueを返す)を直接渡して使います。
    • そして、抽出された見えない状態の結果を、外側を囲んでいるlist()関数によって、私たちが扱える[2, 4, 6] というリストの形に変換して変数に代入しています。

辞書が入ったリストを並び替える

リストには、中身のデータを順番通りに並び替える(ソートする)ためのsort()という便利な機能(メソッド)が最初から用意されています。例えば、数字のリストなら小さい順に、文字のリストならアルファベット順などに自動で並び替えてくれます。

しかし、リストの中に「辞書」が入っている場合、Pythonは「辞書の中のどのデータを基準にして並び替えればいいのか」が分かりません。そこで、並び替えの基準となるルールを直接指定するために、lambda式が非常に役に立ちます。

では、リストのsort()メソッドにlambda式を組み合わせて辞書を並び変えるプログラムを実行してみましょう。

# 辞書が入ったリスト (ユーザーの情報)を用意する
users = [
    {"name": "Alex", "age": 25},
    {"name": "Bob", "age": 20},
    {"name": "Corrin", "age": 30}
]

# usersを「年齢(age)が若い順」に並び替える
# sortの基準(key)として、「受け取った辞書xの中から'age'の値を返す」lambda式を渡す
users.sort(key=lambda x: x["age"])

# 並び替えた結果を表示する
print("年齢順に並び替えた結果:")
for user in users:
  print(f"{user['name']}さん ({user['age']}歳)")

とセルに入力して実行してみましょう。すると結果は

年齢順に並び替えた結果:
Bobさん (20歳)
Alexさん (25歳)
Corrinさん (30歳)

のように表示されます。

プログラムの解説(辞書の並び替え)

  • 並び替えるデータの準備(2~6行目): リストの中に、名前(name)と年齢(age)のデータを持った「辞書」が複数入っています。
  • lambda式を使った並び替えの実行(10行目): users.sort(key=lambda x: x["age"]) と記述しています。リストのsort() メソッドは通常、数字や文字を順番に並び替えますが、「辞書」が相手だと何を基準にすればいいか分かりません。そこでkey= という仕組みを使ってルールを教えます。具体的には次のような順番で処理が行われます。ここで指定した lambda x: x["age"] によって、sort()はリストの中の辞書を1つずつxに取り出し、その中の x["age"] (年齢の数値)を引っ張り出します。そして、取り出した年齢の数値を基準にしてリスト全体を綺麗に並び替えます。わざわざ「年齢を取り出すためだけの関数」を def で定義しなくても、一行でルールを渡せるのがlambda式の最大の強みです。
  • 結果の表示(13~15行目): for文を使って、並び替えが終わったリストから一人ずつデータを取り出し、画面に表示しています。

[補足]名前(アルファベット)順に並び替えてみる

lambda式のすごいところは、ルールの変更が簡単な点です。例えば、先ほどは年齢(age)順でしたが、名前のアルファベット順に並び替えたい場合は、lambda式のx["age"]x["name"]に書き換えるだけで一瞬で対応できます。

# 辞書が入ったリスト (ユーザーの情報)を用意する
users = [
    {"name": "Corrin", "age": 30},
    {"name": "Alex", "age": 25},
    {"name": "Bob", "age": 20}

]

# usersを「アルファベット順」に並び替える
# sortの基準(key)として、「受け取った辞書xの中から'name'の値を返す」lambda式を渡す
users.sort(key=lambda x: x["name"])

# 並び替えた結果を表示する
print("アルファベット順に並び替えた結果:")
for user in users:
  print(f"{user['name']}さん ({user['age']}歳)")

とセルに入力して実行してみましょう。すると結果は

アルファベット順に並び替えた結果:
Alexさん (25歳)
Bobさん (20歳)
Corrinさん (30歳)

のように表示されます。このように、lambda式を使えばx["name"]x["age"]などのキーを少し書き換えるだけで、自分の好きな基準で自由自在に並び替えができるようになります。

まとめ

今回は、「lambda(ラムダ)式」について解説しました。

  • lambda式とは: defで名前を付けるほどでもない、小さな処理を一行で書くための書き方。
  • 書き方のルール: lambda 引数: 返り値となる式 の形式で記述する。
  • returnの省略: コロンの右側に書いた式の計算結果が自動的に返されるため、returnと書く必要がない。
  • 実践的な使い道: filter()での抽出やリストのsort()など、「別の関数に対して、抽出や並び替えのルールとなる処理を直接渡したい時」に非常に便利。
  • list()関数の活用: filter()のように特殊な結果を返すものは、全体をlist()で囲むことで見慣れたリストの形に戻すことができる。

便利な機能ですので、ぜひ使ってみてください。

open-in-colab

今回はこれで終了です。
今回のサンプルを用意したので、もし必要な場合は上の「Open in Colab」と書いてあるボタンをクリックしてください。なおそのままだと編集不可なので編集をしたい場合は「ドライブにコピー」をクリックしてコピーしてください。
なおGoogle ColaboratoryについてわからなかったらGoogleColaboratoryを使ってみよう_導入編をご覧ください。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA