はじめに
Pythonで辞書をソートしたい時に検索すると出てくるlambdaってなに? という疑問から調べてみることにしました。どうやらlambdaとは無名関数のことでdef文を使わないので関数名を付けなくて良いし、変数に直接戻り値を返すことができる便利な使い捨ての関数ということがわかりました。使用例を見ながら解説したいと思います。間違っている箇所などありましたら教えてもらえるとありがたいです。
辞書をソートする例
まずは基本からいきましょう。以下のような辞書があったとします。
data = {'apple': 3, 'banana': 2, 'orange': 4, 'grape': 1}
この辞書をキーや値でソートする方法を見てみましょう。
キーでソートする (x: x[0])
sorted_by_key = dict(sorted(data.items(), key=lambda x: x[0]))
print(sorted_by_key)
実行結果:
{'apple': 3, 'banana': 2, 'grape': 1, 'orange': 4}
値でソートする (x: x[1])
sorted_by_value = dict(sorted(data.items(), key=lambda x: x[1]))
print(sorted_by_value)
実行結果:
{'grape': 1, 'banana': 2, 'apple': 3, 'orange': 4}
降順でソートする
もし降順でソートしたい場合は、sorted関数に reverse=True オプションを追加します。例えば、値で降順ソートを行う場合は次のように書けます。
sorted_by_value_desc = dict(sorted(data.items(), key=lambda x: x[1], reverse=True))
print(sorted_by_value_desc)
実行結果:
{'orange': 4, 'apple': 3, 'banana': 2, 'grape': 1}
このreverse=Trueを付けるだけで、ソート結果が逆順になります。もちろん、キーで降順ソートする場合も同様に使えます。
x: x ってどういう意味?
ここで出てきた lambda x: x[0] や lambda x: x[1] という表記について説明します。
x は、lambda に渡される引数の名前です。実際には x じゃなくても何でも構いません。たとえば、item: item[0] や pair: pair[0] としても同じです。
x[0] や x[1] は、渡された引数から何を返すかを指定しています。ここでは x に渡されるのが (key, value) 形式のタプルなので、x[0] でキー、x[1] で値を取り出しています。
要するに、lambda x: x[0] は「引数として渡されたタプルの最初の要素(つまりキー)を返す関数を定義する」という意味なんです。そして、このキーを使ってソートが行われています。名前は x じゃなくてもいいんですが、短いからよく使われるだけです!
他にもこんなにある!lambdaの活用例
lambdaはソート以外でも幅広く使えます。次は、異なるシーンでのlambdaの使い方を紹介します。
1. リストの中の辞書を値でソートする
例えば、以下のように複数の辞書が含まれるリストがある場合:
data = [{'name': 'apple', 'price': 100}, {'name': 'banana', 'price': 80}, {'name': 'orange', 'price': 120}]
これをpriceでソートするには:
sorted_data = sorted(data, key=lambda item: item['price'])
print(sorted_data)
結果:
[{'name': 'banana', 'price': 80}, {'name': 'apple', 'price': 100}, {'name': 'orange', 'price': 120}]
2. リストのフィルタリング
リストから条件に合う要素だけを抽出したいときにもlambdaは便利です。
numbers = [5, 10, 15, 20, 25]
filtered_numbers = list(filter(lambda num: num > 15, numbers))
print(filtered_numbers)
結果:
[20, 25]
3. リストの各要素を加工する
リストの各要素に対して何かしらの処理をしたいとき、mapとlambdaの組み合わせが使えます。
numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(lambda n: n ** 2, numbers))
print(squared_numbers)
結果:
[1, 4, 9, 16, 25]
4. 複数条件でのソート
例えば、名前と年齢を持つリストを名前でソートし、名前が同じ場合は年齢でソートすることもできます。
people = [{'name': 'John', 'age': 25}, {'name': 'John', 'age': 20}, {'name': 'Jane', 'age': 30}]
sorted_people = sorted(people, key=lambda p: (p['name'], p['age']))
print(sorted_people)
結果:
[{'name': 'Jane', 'age': 30}, {'name': 'John', 'age': 20}, {'name': 'John', 'age': 25}]
5. 簡単な条件分岐
lambdaで簡単な条件分岐もできます。例えば、数が偶数か奇数かを判定して結果を返す:
check_even = lambda num: 'Even' if num % 2 == 0 else 'Odd'
result = check_even(10)
print(result)
結果:
Even
まとめ
lambdaは短く書ける無名関数で、辞書のソート以外にもリストの加工やフィルタリング、複数条件のソートなど多くの場面で使えます。reverse=Trueオプションで簡単に降順ソートもできるので、用途に合わせて使い分けてみてください!もちろん、変数名は x じゃなくてもOKです。ぜひ色々な場面で試してみてください!