順番に読み進めながら学べます

ラムダ式 lambda — 名前なし関数を 1 行で書く

Python のラムダ式 lambda を基礎から解説します。1 行で書く名前なし関数の書き方と高階関数との組み合わせまで図解で押さえます。

前回の高階関数では、関数を引数や戻り値として扱う仕組みを学びました。コールバックを渡すたびに def で関数を定義していると、1 行で済む処理にも 3〜4 行かかってしまいます

そこで使われるのが、名前なしの関数を 1 行で書く ラムダ式lambda)です。def で書くほどでもない小さな処理を、その場でサッと作れます。

ラムダ式とは — def と比べた書き方

ラムダ式の構文は lambda 引数: 式 です。 の評価結果がそのまま戻り値になり、return は書きません(書くと SyntaxError)。

通常の関数と違って名前を持たないため、変数に代入しなければ呼び出すことができません。代入した変数名がそのままその関数の名前として使われます。

def とラムダ式の対応
def 版def add_tax(p): return int(p*1.1)lambda 版add_tax = lambda p: int(p*1.1)1 行に圧縮
def で 4 行書く小さな関数は、lambda なら 1 行で書けます。return は不要で、: の後ろの式の値がそのまま返されます。
# def で書いた場合
def add_tax(price):
    return int(price * 1.1)

print(add_tax(980))   # 1078

# 同じ処理をラムダ式で(return は書かない)
add_tax = lambda price: int(price * 1.1)

print(add_tax(980))   # 1078

「式」だけが書ける — 文は書けない

ラムダ式の本体には式(評価して値になるもの)しか書けませんif 文for 文・代入文(=)はそのまま書けず、複雑な処理を入れたくなったら素直に def に戻すのが正解です。

商品価格に消費税(10%)を上乗せした税込価格を求める関数を 1 行で書いてみましょう。

① 価格を受け取って税込価格(整数)を返す関数を用意してください。

980 円と 2480 円で呼び出して、それぞれの税込価格を表示してください。

(正しく実行できれば解説が表示されます)

Python エディタ

コードを実行してください

引数を増やす・条件式・デフォルト引数

ラムダ式は複数の引数も受け取れます。lambda x, y: x * y のようにカンマで区切って並べるだけです。

さらに、def の引数と同じくデフォルト引数も使えます。条件で値を切り替えたいときは三項演算子 値1 if 条件 else 値2 を式の中に書きます。

# 複数引数
rect_area = lambda width, height: width * height
print(rect_area(4, 5))            # 20

# デフォルト引数(rate を省略すると 0.1 として計算)
add_tax = lambda price, rate=0.1: int(price * (1 + rate))
print(add_tax(1000))              # 1100
print(add_tax(1000, 0.08))        # 1080

# 三項演算子で条件分岐
judge_age = lambda age: "成人" if age >= 20 else "未成年"
print(judge_age(25))              # 成人
print(judge_age(17))              # 未成年

# タプルで複数の値を返す
stats = lambda x, y: (x + y, x * y)
print(stats(3, 4))                # (7, 12)
lambda の引数バリエーション
lambda x, y: x * y複数引数lambda x, y=2: x**yデフォルト引数lambda x: "+" if x>0 else "-"三項演算子で分岐
lambda複数引数・デフォルト引数・三項演算子による分岐まで def と同じ感覚で書けます。

購入ポイントに応じて会員ランク(GOLD / SILVER / BRONZE)を返す処理を 1 行で書いてみましょう。1000 以上で GOLD500 以上で SILVER、それ未満は BRONZE です。

① ポイントを受け取って会員ランクを返す関数を用意してください。

1500 / 700 / 100 の 3 つで呼び出して、判定結果を表示してください。

Python エディタ

コードを実行してください

高階関数と組み合わせる — ラムダ式の本領

ラムダ式の本当の出番は、高階関数の引数として「使い捨ての関数」を渡したいときです。たとえば sorted()key 引数は、「並び替えのときに各要素から取り出すキーを返す関数」を受け取る高階関数です。

名前を付けて再利用するほどでもない並び順の指定は、key=lambda x: x["price"] のようにその場で書いて渡すのが最も自然です。

products = [
    {"name": "ノート", "price": 480},
    {"name": "ペン",   "price": 120},
    {"name": "消しゴム", "price": 80},
]

# 価格の安い順に並び替え(key にその場でラムダを渡す)
cheap_first = sorted(products, key=lambda item: item["price"])
for item in cheap_first:
    print(item["name"], item["price"])
# 消しゴム 80
# ペン 120
# ノート 480

# 同じ高階関数 process_list でも、ラムダで処理を切り替えられる
def process_list(numbers, func):
    for n in numbers:
        print(func(n))

process_list([1, 2, 3, 4], lambda x: x ** 2)
# 1
# 4
# 9
# 16
sorted の key にラムダを渡す流れ
products(辞書のリスト)key=lambda item: item["price"]値段の安い順に並んだ新しいリスト各要素に適用key の値で 並び替え

ユーザーリストをスコアの高い順に並び替えてみます。sorted()reverse=True降順にできます。

users = [{"name": "太郎", "score": 78}, {"name": "花子", "score": 92}, {"name": "次郎", "score": 65}] を用意してください。

sorted(users, key=lambda u: u["score"], reverse=True) で並び替えて変数 ranking に代入してください。

for u in ranking:print(u["name"], u["score"]) を表示してください。

Python エディタ

コードを実行してください

ラムダ式の使いどころと避けどころ

ラムダ式は便利ですが、何でもラムダで書くのは逆に読みにくくなります。次の表のように、使い捨て・1 行で済む処理ならラムダ、複雑・繰り返し使う処理なら def、と棲み分けるのがおすすめです。

場面おすすめ理由
sorted の key, filter, map に渡すlambda1 行で意図が伝わり、名前を付ける必要もない
税込み計算など 1 行で済む式lambda短い名前で関数化でき、import なしで使える
if / for / try が必要な処理deflambda は式のみ。文を書こうとすると SyntaxError になる
複数の場所から再利用される処理def名前で意図が伝わり、テストやドキュメントを書ける
3 行以上の中身になる処理deflambda に詰め込むほど読みづらくなる

「lambda に何でも詰め込む」は禁物

三項演算子を 3 段重ねたり、複数の関数呼び出しを連結したりすると、1 行に収まっていても意味が読み取れないコードになります。「この lambda が何をしているか、コメントを書きたくなった」と感じたら、def を使いましょう。

process_list という高階関数に、その場で作ったラムダ式を渡してみます。

def process_list(numbers, func): を定義し、for n in numbers:print(func(n)) を呼んでください。

process_list([1, 2, 3, 4, 5], lambda x: x ** 2) を呼び出して、各要素の 2 乗が順に表示されることを確認してください。

③ もう一度 process_list([1, 2, 3, 4, 5], lambda x: x * 10) を呼び出して、ラムダ式を渡し変えるだけで処理が変わることを確認してください。

Python エディタ

コードを実行してください
QUIZ

理解度チェック

まずは1問ずつ答えてみましょう。

Q1次のうち、正しいラムダ式はどれですか?

Q2次のコードを実行したときの出力はどれですか?
f = lambda x, y=3: x ** y
print(f(2))

Q3次のうち、ラムダ式の使い方として最も適切なものはどれですか?