ラムダ式
ラムダ式
ラムダ式(lambda expression) は無名関数(anonymous functionあるいはnameless function)とも呼ばれ、プログラミング言語の種類や文化によって表記が違うものの、同じ意味で使われています。
匿名関数(Anonymous Funcrion)
ラムダ関数
ラムダ式
ラムダの抽象化
ラムダ形式
関数リテラル
ここでは、ラムダ式として表記します。
簡単にいうとラムダ式とは名前のない関数のことです。Pythonでは、lambdaキーワードで無名関数を作成します。もっと大雑把に言うと、名前を付けても付けなくてもいいのです。変数に束縛されない、2つの引数を持つ無名関数がlambdaで定義されているとします。このラムダ式には名前がついていません。
関数のような定義をひとつの式として記述することができます。
code: lambda式の記述方法
lambda 引数:処理
2つの引数を加算する関数 add() を例にしてみましょう。
code: 0201_simple_add.py
def add(a, b):
return a + b
c = add(1, 2)
print(c)
これをlambda式を使うと次のように記述することができます。
code: 0202_lambda_add.py
add = lambda a, b: a + b
c = add(1, 2)
print(c)
この例では、lambda式が変数addに設定されていて、addを関数として実行しています。
次の例を見てみましょう。
code: 0203_lambda_add_with_dict.py
data = {'a': 4, 'c':2, 'b': 3, 'd': 1}
# Keyでのソート
result=sorted(data.items())
print(result)
# Valueでのソート
result=sorted(data.items(), key=lambda x: x1) print(result)
辞書型のデータ data があり、これを組み込み関数 sorted() で処理すると、keyでの並び替えに’なります。sorted() には並び順を指定する引数keyがあり、関数を与えることができます。ここにlambda式を書くとわざわざ関数を定義しなくてもよく、プログラムを簡潔に記述できます。
map関数と組み合わせて使用
組み込み関数 map() と組み合わせて使うと、リスト要素を一括して処理させたりすることが簡単に記述できます。
code:map()の使用方法
map( 処理させる関数, リスト)
まず、次のようなリスト要素を2乗する処理を見てみましょう。
code: 0204_square_simple.py
squared = []
for d in data:
squared.append(d**2)
print(squared)
これを、map() と lambda式を組み合わせると次のようにfor文を書かなくても実装できるようになります。
code: 0205_square_lambda_map.py
squared = list(map(lambda x: x**2, data))
print(squared)
filter関数との組み合わせて使用
組み込み関数 filter() と組み合わせて使うと、リスト要素から抜き出すような処理が簡単に記述できます。
code:filter()の使用方法
filter( 処理させる関数, リスト)
次の例は、リストから負数の要素を抜き出す処理を for文で実装したものです。
code: 0206_pickout_vals_simple.py
numbers = range(-5, 5)
negatives=list()
for num in numbers:
if num < 0:
negatives.append(num)
print(negatives)
これを、filter() と lambda式を使うと次のように記述できます。
code: 0207_pickout_vals_lambda_filter.py
numbers = range(-5, 5)
negatives = list(filter(lambda x: x < 0, numbers))
print(negatives)
reduce関数と組み合わせて使用
標準ライブラリ functools の関数reduce()は、リストに対して何らかの計算を実行し、その結果を返す非常に便利な関数です。
code:reduce()の使用方法
reduce( 処理させる関数, リスト)
リスト要素の積を求める処理を、forループで記述したものを見てみましょう。
code: 0208_product_simple.py
product = 1
for num in data:
product = product * num
print(product)
# Output: 24
これを、reduce() と lambda式を使うと次のように記述できます。
code: 0209_product_lambda_reduce.py
from functools import reduce
product = reduce((lambda x, y: x * y), data)
print(product)
# Output: 24
辞書と組み合わせた利用
Pythonには他言語であるような switch 文はありませんが、同様の分岐構造は定義することができます。
単純にif文で実装すると次のようになります。
code: 0210_emulate_switch_simple.py
def dispatcher(operator, x, y):
if operator == 'add':
return x + y
elif operator == 'sub':
return x - y
elif operator == 'mul':
return x * y
elif operator == 'div':
return x / y
else:
return None
print(dispatcher('mul', 3, 5))
print(dispatcher('abc', 3, 5))
これをlambda式と辞書を使って実装すると次のようにスッキリと記述することができます。(少しトリッキーですが...)
code: 0211_emulate_switch_with_dict_lambda.py
def dispatcher(operator, x, y):
dispatch_dict = {
"add": lambda: x + y,
"sub": lambda: x - y,
"mul": lambda: x * y,
"div": lambda: x / y,
}
# dispatch_dict.get() が返すのは関数だから括弧が必要
return dispatch_dict.get(operator, lambda: None)()
print(dispatcher("mul", 3, 5))
print(dispatcher("abc", 3, 5))
dictオブジェクト.get(k, d) を実行すると、キーk が辞書にあれば、
dictオブジェクト[k] の値を返し、なければd の値を返します。
つまり、関数dispatcher() が受け取る引数 operator が、辞書dispatch_dictに登録されていればラムダ式で定義した処理の結果が返されるわけです。
if文での実装と違って条件判断が不要になるので速度的なメリットもあります。
参考: