【Python】ラムダ式とは?メリットや使い方を初心者向けに解説
はじめに
Pythonを学び始めると、関数を定義する方法として def を使うことが一般的ではないでしょうか。
しかし、ちょっとした処理を一度きりで使うために、長々とした関数定義をするのは面倒だと感じる人もいるかもしれません。
そんなときに役立つのが ラムダ式 です。
ラムダ式は、短いコードで関数のような振る舞いを実装する方法といえます。
はじめは慣れないかもしれませんが、特定の場面でコードをすっきりまとめるのに役立ちますので、一度覚えておくと便利です。
この記事を読むとわかること
- ラムダ式とは何か
- 通常の関数との違い
- ラムダ式の基本的な書き方
- 実務での活用シーンや注意点
- 他の構文や組み込み関数との組み合わせ方法
ラムダ式とは何か?
ラムダ式 とは、簡単にいえば「無名関数」を定義するための書き方です。
通常、Pythonで関数を定義するときは def キーワードを使い、関数名や引数などを定義します。
一方で、ラムダ式はあえて関数名を付けず、インラインで動作を書くことができます。
例えば、ある処理を一度だけサッと記述したいときに、ラムダ式が便利です。
実務では、リストなどのデータを加工するときや、何かをソートするときなど、最小限のコードで処理を書く場面が結構あります。
そこで、ラムダ式を使うとコードの見通しが良くなることがあります。
ただし、無理に使うとコードが読みにくくなってしまうので、使いどころを抑えることが大切です。
実際の場面では「この処理を、名前を付けるほどでもないけど、ほんの少しだけ変換したい」という場合にうまく使えるケースがあります。
それにより、行数を減らして短い記述で処理をまとめることができるため、特に一時的なデータの変換などで役立ちます。
通常の関数との違い
ラムダ式は、def を使って定義する関数と何が違うのでしょうか。
大きな違いとしては次のような点が挙げられます。
1. 関数名がない
ラムダ式は名前を持たずに処理を記述します。通常の関数は必ず関数名を持っています。
2. シンプルな処理に向いている
ラムダ式は1行で完結する処理を書くことがほとんどです。長い処理には不向きといわれています。
3. 可読性の問題
無名関数なので、読み手が見たときに「何のために定義されているか」がわかりにくいケースもあります。一方で、単純な処理を短く書けるという利点があります。
4. 構文上、return を書かない
ラムダ式の中では return キーワードを明示的に書くことはできません。処理結果をそのまま返す形で表現します。
たとえば、複数行にわたってコードを書く必要がある場合は、素直に def を使った関数を定義する方がはるかにわかりやすいです。
一方で、一次的に「引数をちょっと加工するだけ」のような場面には、ラムダ式が合っています。
そのため実務の現場でも、「コードを短く書きたい」「使い捨ての処理をちょっと定義したい」というときによく使われます。
ラムダ式の基本的な書き方
ラムダ式の書き方はシンプルで、以下のような構文を使います。
lambda 引数: 処理
たとえば、引数を受け取って2倍にして返すラムダ式は次のように書くことができます。
double_func = lambda x: x * 2 print(double_func(5)) # 10 と出力される
このように、lambda
というキーワードの後ろに引数、そしてコロンのあとに「返したい式」を書きます。
もし引数がないなら、丸括弧の中を空にするか、それ自体省略して lambda: 値
のような形にすることができます。
複数の引数を取る場合も同様に、カンマ区切りで引数名を列挙し、コロンのあとの式で計算を行います。
sum_func = lambda a, b: a + b print(sum_func(3, 4)) # 7 と出力される
このように、名前付き関数を作る代わりに、その場で短い処理を実装できるのがラムダ式の特徴です。
ただし、先ほど述べたように複雑な処理を記述すると可読性が下がる可能性があります。
あくまで1行で表現できる単純な処理にとどめるのが無難といえるでしょう。
実務での活用シーン
実務では、データの加工や、小さな変換処理を適用する場面が多くあります。
例えば、Webアプリケーションでフォームから受け取ったデータを少し加工したいとか、リストの要素をフィルタリングしたい、部分的に変換をかけたいといったケースです。
そうした場合に、わざわざ大きな関数を用意せずに、一時的な処理としてラムダ式を使うとスッキリと書けます。
また、ソートの際に key パラメータを指定して、どのようにデータを比較するかを動的に決めたいことがあります。
そこでラムダ式を使うと、一時的に「ソート基準」を決める関数のようなものを簡潔に指定できます。
例えば、以下の例では文字列リストを「小文字に変換した上で辞書順に並べる」ようにソートしています。
words = ["Banana", "apple", "Cherry"] words.sort(key=lambda x: x.lower()) print(words) # ['apple', 'Banana', 'Cherry']
この場面では「わざわざ関数を定義するほどでもないけど、ソート基準は少し工夫したい」というニーズがあり、ラムダ式で解決しています。
日常的なデータ処理や小さな演算など、ラムダ式はちょっとした便利ツールとして開発者に重宝されることが多いです。
map, filter, reduce 関数との組み合わせ
Pythonには map, filter, reduce といった組み込みの関数があり、これらとラムダ式を一緒に使うケースが多く見られます。
map 関数
map 関数は、リストなどのイテラブルなデータに対し、各要素を変換する関数を適用するための仕組みです。
以下は、数値リストの各要素を2倍にする例です。
numbers = [1, 2, 3, 4] doubled = list(map(lambda x: x * 2, numbers)) print(doubled) # [2, 4, 6, 8]
ここでわざわざ大きな関数を用意せず、ラムダ式を使って変換処理をさくっと書いています。
filter 関数
filter 関数は、リストなどの要素を条件によって絞り込む仕組みです。
条件を関数として定義しますが、ラムダ式で記述すると次のようにコンパクトになります。
numbers = [1, 2, 3, 4, 5, 6] evens = list(filter(lambda x: x % 2 == 0, numbers)) print(evens) # [2, 4, 6]
このように、一時的な判定をする場合でもラムダ式が便利です。
reduce 関数
reduce 関数は、リストなどの要素を「畳み込み」ながら1つの値にまとめるときに使われます。
Python 3系では functools モジュールからインポートして使うことが多いです。
from functools import reduce numbers = [1, 2, 3, 4] total = reduce(lambda a, b: a + b, numbers) print(total) # 10
リストの要素を順番に足し合わせて合計を求めるような場面で、ラムダ式によって短い記述が可能です。
このように、ちょっとした変換や絞り込みを行うときに、ラムダ式と map/filter/reduce を組み合わせると効率が上がります。
ラムダ式とリスト内包表記の違い
Pythonには、リスト内包表記 という機能もあります。
これはリストを生成するときに、直感的な構文で要素に対する操作を1行で書くことができる仕組みです。
例えば、数値リストの各要素を2倍にして新しいリストを作りたい場合、リスト内包表記なら次のように書けます。
numbers = [1, 2, 3, 4] doubled_list = [x * 2 for x in numbers] print(doubled_list) # [2, 4, 6, 8]
見てわかる通り、この書き方もとてもシンプルです。
では、ラムダ式とリスト内包表記はどのように使い分けるのでしょうか。
明確に「関数」という形で抽象化したい
mapやfilterなどに渡したい場合、ラムダ式がわかりやすいことがあります。
新しいリストを1ステップで構築したい
リスト内包表記の方が表現しやすい場合が多いです。
たとえば、map(lambda x: x * 2, numbers)
は見た目にラムダ式が登場しますが、内包表記 [x * 2 for x in numbers]
の方が慣れやすいという意見もあります。
どちらを使うかは好みや読みやすさに左右される部分が大きいのですが、「複数の関数をチェーンのようにつなげたい」「コードを大きく分割して読みやすくしたい」場合には map/filter/reduce+ラムダ式が選ばれることも少なくありません。
一方で、リスト内包表記の方がスッキリと書ける、というケースも多いです。
最終的には、チームの方針や自身の書きやすさ、可読性などを総合的に考えて選ぶと良いでしょう。
ラムダ式を使う上での注意点
ラムダ式は便利ですが、使い方を誤ると困ったことになる場合もあります。
最大のポイントは 「可読性」 です。
1行で書けるのでつい乱用してしまうと、ラムダ式が連続するコードになり、何をやっているのか一見わかりにくくなることがあります。
また、複雑なロジックをラムダ式に押し込めると、保守性が下がりがちです。
無名関数なので、意味づけが曖昧になるケースもあります。
複雑な処理が必要な場合は def を使った関数定義に切り替え、名前を付けてあげたほうが読みやすいケースが多いです。
さらに、ラムダ式内では基本的に return を書けないため、「途中で条件分岐をして、ある場合には何かを返し、別の場合は別の値を返す」といった複雑なロジックには向きません。
やろうと思えば三項演算子などで書ける場合もありますが、無理に詰め込みすぎると後から読む人が苦労します。
以下のような点を押さえておくとスムーズでしょう。
- 単純な処理を1行で書きたい場面に絞る
- あいまいなロジックを避け、誰が読んでも意図が伝わるように配慮する
- チームのコーディング規約や方針を考慮して使いすぎを避ける
チームメンバー全員が理解しやすいコードを書くことが、とても大切です。
ラムダ式は適度に使えば役立つツールですが、過剰に使うとメンテナンスが大変になりやすいという点に注意するとよいでしょう。
まとめ
ここまで、Pythonのラムダ式について解説してきました。
ラムダ式は「無名関数」として、短いコードでちょっとした変換や判定処理を書きたいときにとても便利です。
しかし、複雑なロジックには不向きで、可読性を損なう可能性もあるため、使い方を誤らないことが大切です。
初心者の方はまずは小さな処理をラムダ式で表現してみて、どんな場面で役立つか感覚をつかむと良いかもしれません。
その上で、map や filter と組み合わせたり、ソートの key 引数として使ってみたりして、コードを手軽に短くまとめる方法を身につけてみてはいかがでしょうか。