【Python】ラムダ式(lambda)の書き方【入門第45回】
目次
ラムダ式とは?
こんにちは、narupoです。
今回はPythonのラムダ式(lambda)をやっていきます。
ラムダ式は、小さい名前のない関数を作るときに使います。
これを知っておくと、sorted
関数などを便利に使うことができます。
ラムダ式について、具体的には↓を見ていきます。
ラムダ式の書き方
関数オブジェクトを変数に入れる
関数オブジェクトを実行する
関数オブジェクトに引数を渡す
sorted関数でラムダ式を使う
ラムダ式の書き方
ラムダ式は↓のように書きます。
:::text
lambda: 式
例えば1 + 1
を計算するラムダ式は↓のように書きます。
:::python
lambda: 1 + 1
ラムダ式は基本的には1行で書きます。
なので複数行のラムダ式はサポートされていません。
複数行で書きたい場合は↓のように改行をエスケープします。
:::python
lambda: 1 \
+ \
1
↑は先ほどと同様に1 + 1
を計算するラムダ式です。
関数オブジェクトを変数に入れる
↓のようにするとラムダ式で作られた関数オブジェクトを変数に入れることができます。
:::python
func = lambda: 1 + 1
変数func
は関数オブジェクトです。
print(type(func))
でタイプを出力すると↓のようになります。
<class 'function'>
function
(関数)ですね。
関数オブジェクトを実行する
↓のような関数オブジェクトを実行するには、ふつうに関数を呼び出すように実行します。
:::python
func = lambda: 1 + 1
func()
↑のfunc()
で関数オブジェクトを実行しています。
ここでラムダ式の特徴について解説します。
ラムダ式には↓のようにreturn
文は書けません。
:::python
lambda: return 1
ラムダ式は式ですので、↓のような1 + 1
の演算結果はそのまま参照することができます。
:::python
lambda: 1 + 1
これはどういうことかいうと、たとえば↓のように関数オブジェクトを実行してみましょう。
:::python
func = lambda: 1 + 1
print(func())
↑の結果は2
になります。
ラムダ式にはreturn
文などはありませんが、関数オブジェクトの実行結果はちゃんと返ってきてます。
ですので↓のように演算することも可能です。
:::python
func = lambda: 1 + 1
result = func() * 3
print(result)
↑のコードの実行結果は6
になります。
関数オブジェクトに引数を渡す
関数オブジェクトには関数のように引数を渡すことも出来ます。
ラムダ式では引数を受けるときにどのように書くのかと言うと、↓のように書きます。
:::text
lambda 引数: 式
lambda 引数, 引数, ...: 式
たとえば引数x
を取りたい場合は↓のように書きます。
:::python
lambda x: x * 2
↑は引数x
を単純に2倍にするラムダ式です。
複数の引数、たとえばx
とy
を取りたい場合は↓のようにします。
:::python
lambda x, y: x * y
↑のように複数の引数を書くときはカンマ(,
)で区切ります。
↓のような複数の引数を取る関数オブジェクトを呼び出すときは、ふつうの関数呼び出しと同じです。
:::python
func = lambda x, y: x * y
result = func(2, 3)
print(result)
↑のコードの実行結果は6
になります。
あとはラムダ式の引数にも、関数と同じように引数のデフォルト値や、*args
や**kwargs
なども書くことができます。
:::python
lambda x=2: x * 2
lambda *args: len(args)
lambda *args, **kwargs: len(kwargs)
sorted関数でラムダ式を使う
ラムダ式の実践的な使用例として、sorted
関数によるリストのソートの例を紹介します。
sorted
関数はリストなどをソートする関数です。
例えば↓のようにするとリストを昇順にソートすることができます。
:::python
lst = [3, 1, 2]
sorted_lst = sorted(lst)
print(sorted_lst)
↑のコードの実行結果は↓のようになります。
[1, 2, 3]
↑のような数値のリストは簡単にソートできますが、↓のように独自クラスのインスタンスが入っているリストのソートはどうなるでしょうか。
:::python
class Cat:
def __init__(self, age):
self.age = age
cats = [
Cat(3),
Cat(1),
Cat(2),
]
sorted_cats = sorted(cats)
↑のコードの実行結果は↓のようになります。
Traceback (most recent call last):
File ".\sample.py", line 11, in <module>
sorted_cats = sorted(cats)
TypeError: '<' not supported between instances of 'Cat' and 'Cat'
このように、普通にソートしようとしてもsorted
はインスタンスをソートしてくれません。
なぜかというと、sorted
関数はインスタンスを何をキーにしてソートしたらいいのかわからないからです。
こういったインスタンスのリストをソートしたい場合は、sorted
関数のkey
引数を使います。
key
引数に関数オブジェクトを渡して、ソートのキーになる値を参照させるようにします。
たとえば↓のようにです。
:::python
sorted(cats, key=lambda cat: cat.age)
↑では、sorted
関数のkey
引数にラムダ式を書いて関数オブジェクトを渡しています。
sorted
関数はソートするときに、この関数オブジェクトを参照して、引数にリストの要素を渡して呼び出します。
lambda cat:
のように第1引数がcat
になっていますが、これがソート時に参照されているリストの要素です。
この要素、つまりCat
クラスのインスタンスを参照して、cat.age
の値を参照するようにしています。
こうすることで、sorted
関数はソートするときに、cat.age
の値をキーにしてソートします。
ですので↓のコードの実行結果は、
:::python
class Cat:
def __init__(self, age):
self.age = age
cats = [
Cat(3),
Cat(1),
Cat(2),
]
sorted_cats = sorted(cats, key=lambda cat: cat.age)
for cat in sorted_cats:
print(cat.age)
↓のようになります。
1
2
3
cats
を昇順にソートできてますね。
他には、Cat
クラスで演算子をオーバーロードする方法もありますが、ここでは解説を割愛します。
おわりに
ラムダ式は書けるとなかなかお洒落かもしれません。
カフェでコードを書いてて、何を書いてるの? と言われて「ラムダ式だよ(どやぁ」と答えることができます。
かっちょいいですね。
……
以上、次回に続きます。
また見てね