Python | 関数:ラムダ式

Python
スポンサーリンク

概要(ラムダ式は「その場で一行の小さな関数」を作るための構文)

ラムダ式は、def を使わずに“その場で”一行で定義できる小さな関数(無名関数)です。書式は「lambda 引数: 式」。戻り値はその“式の値”で、名前を付けずに関数の引数として渡したり、短い処理を差し込むのに向いています。

# x を受け取り、2倍して返す無名関数
double = lambda x: x * 2
print(double(4))  # 8
Python

基本構文と特徴(ここが重要)

式のみ書ける(return や代入などの文は書けない)

ラムダ式の本体は「式」だけです。return、代入、for/while、try、with、print など“文”は書けません。値を計算して返す、という一点に絞るのがコツです。

# できる(式のみ)
f = lambda x: x ** 2

# できない(文を含むため)
# g = lambda x: (y := x + 1)  # ウォルラス演算子は式だが、初心者には def を推奨
Python

無名だが「変数に代入」して使える

ラムダ式自体は名前を持ちませんが、変数に代入すれば再利用できます。ただし、明確な役割を持つ関数は def で名前を付けるほうが可読性・デバッグ性が高いです。

add = lambda a, b: a + b
print(add(3, 5))  # 8
Python

引数の書き方(デフォルト・args・*kwargs も使える)

def と同じく、デフォルト引数、args、*kwargs を使えます。短い「変換」「比較」などでは十分な表現力です。

fmt = lambda s, upper=False: s.upper() if upper else s.strip()
print(fmt("  coffee  "))            # 'coffee'
print(fmt("coffee", upper=True))    # 'COFFEE'
Python

典型的な使いどころ(高階関数の“その場の処理”)

sorted の key に渡して並び替え基準を定義

並び替えの「比較基準」を一行で書けます。複合キーもタプルで簡潔に。

items = [{"name": "tea", "price": 280},
         {"name": "coffee", "price": 350}]
print(sorted(items, key=lambda x: (x["price"], x["name"])))
Python

map・filter の処理を簡潔に記述

要素への“変換”や“選別”を関数を別定義せずに書けます。

nums = [1, 2, 3, 4, 5]
doubled = list(map(lambda x: x * 2, nums))
evens   = list(filter(lambda x: x % 2 == 0, nums))
print(doubled, evens)  # [2, 4, 6, 8, 10] [2, 4]
Python

小さなコールバックやイベントハンドラ

UIや並列処理で「短い一手」を渡すのに向いています。長くなるなら def に切り替えましょう。

apply = lambda xs, op: [op(x) for x in xs]
print(apply([1, 2, 3], lambda x: x + 10))  # [11, 12, 13]
Python

注意点の深掘り(使いどころの線引き・スコープ・遅延束縛)

読みやすさが最優先(複雑なら def)

条件が重なる、処理が2歩以上になる、例外処理が必要——こうなったら躊躇なく def を使ってください。ラムダ式は“短い一行”が原則です。docstring や型ヒントも付けられないため、公開関数は def が適切です。

# NG:読みにくいラムダの例(処理が長い)
# key=lambda x: (x["a"].strip().lower() if x["a"] else "", x["b"] or 0)

# OK:関数化して読みやすく
def sort_key(x):
    a = x["a"].strip().lower() if x["a"] else ""
    b = x["b"] or 0
    return (a, b)
Python

変数キャプチャ(クロージャ)と“遅延束縛”の罠

ラムダ式は外側の変数を参照できますが、ループ内で作ると「最後の値」を参照してしまう典型的な罠があります。現在の値を閉じ込めたいときは“デフォルト引数に束縛”するテクニックを使います。

funcs = []
for i in range(3):
    funcs.append(lambda x, i=i: x + i)  # i=i でその時点の i を固定
print([f(10) for f in funcs])  # [10, 11, 12]
Python

デバッグとトレーサビリティ

ラムダ式は名前が付かないため、トレースやログで関数名が出ずに困ることがあります。再利用や公開APIでは def で名前を与え、必要なら docstring・型ヒントを付けてください。

実践例(現場の“ちょうどいい”ラムダの使い方)

文字列整形のワンショット処理

normalize = lambda s: s.strip().casefold()
texts = ["  Apples ", "TEA", " coffees"]
print(list(map(normalize, texts)))  # ['apples', 'tea', 'coffees']
Python

辞書リストの抽出・整形を一行で

rows = [
    {"name": "coffee", "price": 350, "qty": 2},
    {"name": "tea",    "price": 280, "qty": 0},
]
in_stock = list(filter(lambda r: r["qty"] > 0, rows))
totals   = list(map(lambda r: r["price"] * r["qty"], in_stock))
print(in_stock, totals)  # [{'name': 'coffee', ...}] [700]
Python

複合キーで安定ソート

people = [{"last": "Sato", "first": "Hanako"},
          {"last": "Abe",  "first": "Jiro"},
          {"last": "Sato", "first": "Taro"}]
print(sorted(people, key=lambda p: (p["last"], p["first"])))
Python

関数を返すラムダ(短いファクトリ)

make_rounder = lambda ndigits: (lambda x: round(x, ndigits))
r2 = make_rounder(2)
print(r2(3.14159))  # 3.14
Python

まとめ

ラムダ式は「その場で一行の小さな関数」を作るための道具。式だけを書ける簡潔さが武器で、sorted の key、map・filter の処理、短いコールバックに最適です。複雑になったら迷わず def に切り替える、ループで外側変数を閉じ込めるときはデフォルト引数で束縛する——この二つを守れば、ラムダ式はあなたのコードを鋭く、無駄なく仕上げてくれます。

タイトルとURLをコピーしました