Pythonの関数で、関数funcを引数として使うことをこれまで少し出てきたりしました。これは便利な操作ですけど、いろんな処理をするにはいくつも関数funcを定義してから使う必要が出てきます。
このいくつも定義するって操作は手間がかかりますよね。実際に使う時に関数名を覚えておかないといけません。
これを関数定義を個別にしなくてもいきなり使えると便利です。これを可能にするのがlambdaです。ラムダ式とかラムダ関数といいます。
ここではラムダ式について見ていこうと思います。入門者としては少し発展的な内容になると思います。
ラムダ式を見る前に
ラムダ式をみていく前に、関数funcを引数とする処理を見ておきましょう。そうすることで、lambda式で処理した時の違いを見ることができますから、どんな便利さがあるかを確認したいと思います。
次のようなコードを考えてみます。
gundam_meisters = ["Setsuna", "Lockon", "Allelujah", "Tieria"]
def change_names(names, func):
for name in names:
print(func(name))
def name_func(name):
return name.upper()
change_names(gundam_meisters, name_func)
ガンダムマイスターの名前が入ったリストを用意します。要素からfor文を使って一つずつ抜き出して出力する関数を定義しています。引数にnamesと関数funcを使っています。そして、もう一つ要素をupper()関数で大文字に変換する関数を定義しています。
最初の関数の引数namesにリストを、引数funcに大文字に変換する関数を使ってchange_names()を呼び出しています。
コードを実行してみましょう。ファイル名はlamda.pyとしてAtomで実行しています。
リストの要素が全て大文字になって出力されているのがわかります。
このコードをラムダ式を使うとどうなるかという話になります。
lambda式を利用する
上の式をラムダ式を使って書き換えてみようと思います。引数に使った関数をlambdaを使えば次のように書き換えることができます。
gundam_meisters = ["Setsuna", "Lockon", "Allelujah", "Tieria"]
def change_names(names, func):
for name in names:
print(func(name))
# def name_func(name):
# return name.upper()
name_func = lambda name: name.upper()
change_names(gundam_meisters, name_func)
上で使った関数をコメントアウトしているので、比較して見ることができると思います。2行で書かれていたコードを1行で済ませることができています。
実行してみましょう。
同じ結果が得られています。
ラムダ式をそのまま引数に書き込むこともできます。
gundam_meisters = ["Setsuna", "Lockon", "Allelujah", "Tieria"]
def change_names(names, func):
for name in names:
print(func(name))
change_names(gundam_meisters, lambda name: name.upper())
かなりスッキリしたコードになりますね。
もちろん実行すれば同じ結果が得られます。
lambda式は、その後に引数をおきます。その後ろにコロン(:)をおいて、続けて関数の定義を書いています。
このようにラムダ式を使えば、関数名を使った定義を使わなくて実行できるという利点があります。ここでは関数は一つでしたが、関数をいくつも用意して関数名を覚えながらコードを書いていくということになった場合、とても煩雑になることもあり、そんな時にラムダ式が効果を発揮します。
次のように、関数を別に定義しなくてもラムダ式でいきなり別の操作をできるわけです。
gundam_meisters = ["Setsuna", "Lockon", "Allelujah", "Tieria"]
def change_names(names, func):
for name in names:
print(func(name))
change_names(gundam_meisters, lambda name: name.upper())
change_names(gundam_meisters, lambda name: name.lower())
change_names(gundam_meisters, lambda name: name.swapcase())
関数名を定義せずに、二つ追加していますね。特に別の関数を定義して使っている訳ではありません。
実行するとこうなります。
それぞれ違いがわかりますね。upper()は全て大文字に、lower()は全て小文字に、swapcase()は大文字と小文字を入れ替えているのがわかります。
一番最初の例と同じようにするならば、コードはこうなってしまいます。
gundam_meisters = ["Setsuna", "Lockon", "Allelujah", "Tieria"]
def change_names(names, func):
for name in names:
print(func(name))
def name_func(name):
return name.upper()
def name_func2(name):
return name.lower()
def name_func3(name):
return name.swapcase()
change_names(gundam_meisters, name_func)
change_names(gundam_meisters, name_func2)
change_names(gundam_meisters, name_func3)
実行はしませんが、同じ結果になるのですが、コードが増えてそれぞれの関数名を覚えて呼び出さないといけないのがわかりますね。lamdaを使った時との違いがわかると思います。
まとめ
ラムダを使わなくても、実際の関数を定義して見ていく方が流れとしては見やすい場合があります。
ですが、ラムダ式を使わなければ、いくつも小さな関数を定義して行かなくてはならないし、その関数名を覚えて利用していく必要があります。その点、ラムダ式は関数名前を用意せずに使えるので、その違いを考えるとラムダ式の効果がどういうものかわかると思います。
lambda式は、lambdaの後に引数を書いてコロンを置き、その後ろに関数定義を書きます。
lambdaを使ってコードを書けるとちょっと上級者っぽくてかっこいい感じがしますね。