閉じる

Pythonのラムダ式とは?map/filter/sortedで使う実例集

短い処理を一時的に関数化したいとき、Pythonのラムダ式は強力な選択肢になります。

本記事では、ラムダ式の基本から、map、filter、sortedでの実践的な使い方まで、初心者の方が段階を踏んで理解できるよう丁寧に解説します。

可読性やデバッグのコツも紹介します。

Pythonのラムダ式とは

ラムダ式の意味と用途

ラムダ式とは、名前を付けずにその場で関数を作るための記法(匿名関数)です。

主に一時的なコールバック関数や、簡単な変換関数を渡す場面で使われます。

たとえば、sortedkey引数や、mapfilterなどの高階関数に渡すときに、わざわざdefで関数定義を用意せず、その場で短い処理を記述できます。

基本構文

ラムダ式は1つの「式(expression)」で結果を返します。

文(statement)は書けないため、シンプルな処理に向きます。

lambda 引数: 式

次の書式で書きます。

Python
# 例: 受け取った数値を2倍にするラムダ
double = lambda x: x * 2
print(double(10))  # 20
実行結果
20

引数が複数ある場合も同様です。

Python
# 例: 2つの数値を足すラムダ
add = lambda a, b: a + b
print(add(3, 5))  # 8
実行結果
8

defとの違いと使い分け

ラムダ式とdefの主な違いを整理します。

  • ラムダ式は式ベースで短く書けますが、1つの式しか書けません。
  • defは複文やreturndocstring、型アノテーションなど、通常の関数の機能をすべて使えます。
  • デバッグ時のトレースバックでは、ラムダ式は<lambda>としか表示されないため、識別しづらいことがあります。
  • 可読性の観点から、処理が複雑になったらdefに移行するのが定石です。

以下は違いをまとめた比較表です。

観点lambdadef
構文1つの式のみ複数行・複文が書ける
使いどころ短い一時関数再利用・説明が必要な関数
戻り値式の評価結果returnで任意に制御
デバッグ名称は<lambda>で追いにくい関数名で追いやすい
型ヒント直接は不可可能(パラメータ/戻り値)

できることと制限

ラムダ式は簡潔で便利ですが、制限があります。

代表的なポイントを押さえましょう。

  • 1つの式しか書けません。代入文やfor文、if文(文としてのif)などの複文は不可です。
  • returnは書けません。式の評価結果がそのまま戻り値になります。
  • 例外処理のtry/exceptwith文なども書けません。
  • 型アノテーション(例: x: int)をラムダの引数に直接書くことはできません。型を付けたい場合はdefを使うか、Callableで変数側を注釈します。

以下はNG例です。

Python
# NG: returnは使えません(構文エラー)
# bad = lambda x: return x * 2

# NG: 文は書けません(構文エラー)
# bad = lambda x: for i in range(x): print(i)

map filter sortedで使うラムダ式の実例

mapとラムダ式の基本

map(func, iterable)は、各要素に関数を適用して新しいイテラブルを返します。

ラムダ式を使うと、その場で変換ロジックを書けます。

Python
# 例: リストの各要素を2乗にする
nums = [1, 2, 3, 4]
squares = map(lambda x: x * x, nums)  # mapはイテレータを返す
print(list(squares))  # 出力のためにlist化

# 例: 文字列リストを大文字化
words = ["apple", "Banana", "cherry"]
upper_words = map(lambda s: s.upper(), words)
print(list(upper_words))
実行結果
[1, 4, 9, 16]
['APPLE', 'BANANA', 'CHERRY']

補足として、Pythonicには内包表記でも表現可能です。

可読性重視なら内包表記、既存APIのコールバックに渡すならラムダ、と使い分けると良いです。

filterとラムダ式の基本

filter(func, iterable)は、関数が真と判定した要素だけを通します。

ラムダ式で判定条件を短く書けます。

Python
# 例: 偶数だけを抽出する
nums = [1, 2, 3, 4, 5, 6]
evens = filter(lambda x: x % 2 == 0, nums)
print(list(evens))

# 例: Truthinessでフィルタ(空文字やNoneを除去)
items = ["hello", "", "world", None, " "]
# boolに変換して真のものだけ残す
truthy_items = filter(lambda x: bool(x), items)
print(list(truthy_items))
実行結果
[2, 4, 6]
['hello', 'world', ' ']

filter(None, iterable)とすると、真の値だけを残す簡略記法になります。

Python
items = ["", "A", 0, 1, None, "ok"]
print(list(filter(None, items)))  # Truthyな要素だけ
実行結果
['A', 1, 'ok']

sortedのkeyにラムダ式を使う

sorted(iterable, key=...)list.sort(key=...)では、要素からソート基準を取り出す関数(キー関数)を指定します。

ラムダ式の定番用途です。

Python
# 例: 文字列を長さでソート
words = ["pear", "apple", "banana", "kiwi"]
print(sorted(words, key=lambda s: len(s)))

# 例: 大文字小文字を無視して辞書順ソート
mixed = ["Zoo", "alpha", "Bravo"]
print(sorted(mixed, key=lambda s: s.lower()))
実行結果
['kiwi', 'pear', 'apple', 'banana']
['alpha', 'Bravo', 'Zoo']

複数キーでソートする例: タプルを返すラムダ

複数の基準で並べたいときは、キー関数でタプルを返します。

Pythonはタプルを辞書式順序で比較します。

Python
# 例: (名前, 年齢)のタプルを「年齢昇順→名前昇順」でソート
people = [("Taro", 20), ("Jiro", 20), ("Hanako", 18)]
sorted_people = sorted(people, key=lambda x: (x[1], x[0]))
print(sorted_people)

# 例: 「年齢降順→名前昇順」
# 年齢のみ負にして降順を実現(数値なら有効なテクニック)
sorted_people_desc_age = sorted(people, key=lambda x: (-x[1], x[0]))
print(sorted_people_desc_age)
実行結果
[('Hanako', 18), ('Jiro', 20), ('Taro', 20)]
[('Taro', 20), ('Jiro', 20), ('Hanako', 18)]

もちろん、sorted(..., reverse=True)で全体を逆順にもできますが、キーごとに昇降を混在させたい場合はタプル中で符号を工夫すると表現しやすいです。

辞書リストをソートする例: キー関数で指定

実務では辞書のリストをソートすることが多いです。

キー関数で辞書の特定キーを取り出します。

Python
# 例: 社員情報を年齢→名前で昇順ソート
employees = [
    {"name": "Alice", "age": 30, "dept": "Sales"},
    {"name": "Bob", "age": 25, "dept": "Dev"},
    {"name": "Charlie", "age": 25, "dept": "Dev"},
]
by_age_name = sorted(employees, key=lambda e: (e["age"], e["name"]))
print(by_age_name)
実行結果
[{'name': 'Bob', 'age': 25, 'dept': 'Dev'}, {'name': 'Charlie', 'age': 25, 'dept': 'Dev'}, {'name': 'Alice', 'age': 30, 'dept': 'Sales'}]

標準ライブラリoperatoritemgetterattrgetterを使うと、読みやすく高速な場合があります。

Python
# itemgetterの例(辞書から複数キーを取り出す)
from operator import itemgetter

by_age_name_fast = sorted(employees, key=itemgetter("age", "name"))
print(by_age_name_fast)
実行結果
[{'name': 'Bob', 'age': 25, 'dept': 'Dev'}, {'name': 'Charlie', 'age': 25, 'dept': 'Dev'}, {'name': 'Alice', 'age': 30, 'dept': 'Sales'}]

ネストした値を取り出す例: ラムダで経路指定

ネストが深い辞書からキーをたどってソートしたいこともあります。

無防備にe["profile"]["score"]のように書くと、欠損時にKeyErrorになります。

getを連鎖して安全に取り出す方法が実用的です。

Python
# 例: ネストしたスコアでソート(欠損は0扱い)
users = [
    {"name": "Alice", "profile": {"score": 80}},
    {"name": "Bob", "profile": {}},  # score欠損
    {"name": "Charlie", "profile": {"score": 95}},
]
safe_score = lambda u: u.get("profile", {}).get("score", 0)
print(sorted(users, key=safe_score, reverse=True))
実行結果
[{'name': 'Charlie', 'profile': {'score': 95}}, {'name': 'Alice', 'profile': {'score': 80}}, {'name': 'Bob', 'profile': {}}]

ネストが更に深い場合も、getを重ねるか、専用の取得関数をdefで用意すると読みやすさが向上します。

初心者が押さえるベストプラクティス

可読性を保つコツ

ラムダ式は短さが魅力ですが、短くても読みやすさが最優先です。

引数名は意味がわかる名前にし、式の中で過剰なロジックを詰め込まないようにします。

sorted(key=...)のような「意図が明確なコールバック」に限定して使うと、第三者にも通じやすくなります。

また、似た用途ではoperator.itemgetterattrgetterの利用も検討できます。

ラムダを使わない方が良いケース

処理が複雑、条件分岐が多い、例外処理が必要、または型ヒントやドキュメント文字列を付けたい場合はdefで関数化した方が良いです。

スタックトレースに名前が出るため、運用時の調査や保守も容易です。

1行を超えそうになったらdefへの切り替えを検討してください。

デバッグと例外の注意

ラムダ式はトレースバック上で<lambda>と表示され、どのラムダか判別しづらいことがあります。

デバッグ中は、ラムダを一時的にdefへ置き換える、あるいはラムダを変数に代入して説明的な名前を付けると追跡しやすくなります。

例外は通常どおり上位へ伝播しますが、ラムダの中に過剰な副作用を持ち込まず、「入力を受け取り値を返す純粋な関数」に近づけるとバグを減らせます。

Python
# デバッグしやすい命名
key_by_safe_score = lambda u: u.get("profile", {}).get("score", 0)

コールバック関数での活用ポイント

ラムダ式は「小さな関数をコールバックとして渡す」用途に強いです。

sorted(key=...)mapfilterのほか、re.sub(pattern, repl, s)replに関数を渡して動的に置換文字列を決める、といった応用もあります。

短く明確なロジックをその場で書けるため、関数の定義場所へ移動する手間がなく、コードの流れを追いやすくなります。

逆に、複数箇所で再利用する処理はdefにまとめた方が保守的です。

まとめ

ラムダ式は「短い処理をその場で関数化する」ための記法で、mapfiltersorted(key=...)のような高階関数と非常に相性が良いです。

1つの式しか書けない、returnや複文が使えない、型アノテーションを直接付けられないなどの制約はありますが、その分シンプルで読みやすい場面に最適です。

複雑化したらdefへ切り替える、itemgetterなどと使い分ける、ネスト取り出しは安全に、という基本を押さえれば、Pythonicにコーディング効率を高められます。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!