【Python】forループを1行で書く魔法?「リスト内包表記」を徹底解説!(if文付きも)✨
「リスト作成、まだforループで消耗してる?」
TikTokの動画を見て、この記事にたどり着いた皆さん、ありがとうございます!
動画で紹介した、数行にわたるfor
ループとappend
の処理を、たった1行の美しいコードで実現するPythonのテクニック。それが「リスト内包表記(list comprehension)」です。
「どうしてあんな書き方ができるの?」「読み方が分からない…」そして動画の最後にあった「じゃあ、if文付きはどう書くの?」という疑問。この記事では、そんなあなたの「?」を「!」に変えるため、リスト内包表記の基本的な仕組みから、if
文を使った応用的な使い方まで、分かりやすく徹底的に解説していきます。このテクニックをマスターすれば、あなたのPythonコードはもっと簡潔に、もっとエレガントになりますよ!
1. 復習:基本的なリストの作り方(forループとappend)
まず、動画の「Before」で見た、伝統的で分かりやすいリストの作成方法をおさらいしましょう。例えば、「1から5までの数値をそれぞれ2乗したリスト」を作る場合、以下のように書きますね。
# よくある書き方
squares = [] # 1. 空のリストを用意する
for i in range(1, 6): # 2. 1から5までループする
squares.append(i**2) # 3. 2乗した結果をリストに追加する
print(squares)
実行結果:
[1, 4, 9, 16, 25]
この方法は、処理の流れが追いやすく、プログラミング初心者にとって非常に理解しやすい、正統な書き方です。しかし、Pythonはこのような定型的な処理を、もっとスマートに書くための素晴らしい機能を提供してくれています。
2. リスト内包表記:Pythonicな解決策
それでは、動画の「After」で登場した魔法の1行、リスト内包表記の構造を解き明かしていきましょう。
2.1. 基本の構文:[ 式 for 要素 in イテラブル ]
先ほどのコードは、リスト内包表記を使うと以下のように書けます。
# Pythonなら、これが1行。
squares = [i**2 for i in range(1, 6)]
print(squares)
実行結果:
[1, 4, 9, 16, 25]
結果は全く同じですが、コードはたった1行です!この構文は、3つのパーツに分解して考えると理解しやすくなります。
[
①要素に加えたい式
②forループ
]
- 要素に加えたい式 (
i**2
): ループの各要素(この場合はi
)を使って、最終的にリストの要素として何を入れたいかを記述します。 - forループ (
for i in range(1, 6)
): 通常のfor
文の、コロン(:
)を除いた部分です。どのデータのかたまりを、どの変数名でループさせるかを指定します。 - 角括弧 (
[]
): これら全体を角括弧で囲むことで、「結果としてリストを作成します」ということをPythonに伝えます。
英語の文章のように、「for i in range(1, 6) の各要素 i に対して、i**2 という計算をした結果のリストが欲しい」と読むことができます。
3.【動画の続き】if文を使った条件付きリスト内包表記
お待たせしました!動画の最後で「じゃあif文付きはどう書くの?」と問いかけましたね。リスト内包表記では、if
文もスマートに組み込むことができます。これには書き方が2パターンあります。
3.1. パターン1:要素をフィルタリングするif
文
「特定の条件を満たす要素だけを処理したい」場合に使います。例えば、「1から10までの数値のうち、偶数だけを2乗したリスト」を作りたい場合です。
構文: [ 式 for 要素 in イテラブル if 条件式 ]
if
文はfor
ループの後ろに書きます。
# 1から10までの偶数だけを2乗する
even_squares = [i**2 for i in range(1, 11) if i % 2 == 0]
print(even_squares)
実行結果:
[4, 16, 36, 64, 100]
これは、range(1, 11)
の各要素i
について、まずif i % 2 == 0
の条件がチェックされ、その条件を満たした(True
になった)i
だけが、最初の式i**2
で処理されてリストの要素になる、という流れです。
3.2. パターン2:式自体に条件分岐を含めるif-else
文
「条件によって処理内容を変えたい」場合、つまりif-else
を使いたい場合は、書き方が少し変わります。例えば、「1から10までの数値のうち、偶数は2乗し、奇数はそのままのリスト」を作りたい場合です。
構文: [ Trueの時の式 if 条件式 else Falseの時の式 for 要素 in イテラブル ]
if-else
の塊は、for
ループの前に「式」の一部として書きます。これはPythonの「三項演算子」と呼ばれる書き方です。
# 偶数は2乗、奇数はそのまま
processed_list = [i**2 if i % 2 == 0 else i for i in range(1, 11)]
print(processed_list)
実行結果:
[1, 4, 3, 16, 5, 36, 7, 64, 9, 100]
この2つのif
の書き方の違いは最初は少し混乱するかもしれませんが、「フィルタリングだけならfor
の後ろ、if-else
で処理を分けるならfor
の前」と覚えると分かりやすいです。
4. リスト内包表記のメリット
なぜ多くのPythonプログラマーはリスト内包表記を好んで使うのでしょうか?
- 簡潔で読みやすい (Concise & Readable): 慣れれば、複数行にわたる
for
ループよりも、処理の意図が一行で明確に伝わります。 - パフォーマンスが良い (Performant): 多くの場合、Pythonの内部で最適化されているため、
for
ループと.append()
を組み合わせるよりも高速に動作します。
ただし、何でもかんでもリスト内包表記で書けば良いというわけではありません。もしループのロジックが非常に複雑になったり、ネストが深くなったりする場合は、可読性の観点から、素直に通常のfor
ループで書く方が良い選択であることも覚えておきましょう。
まとめ
TikTokで紹介した「forループを1行で書く魔法」、その正体は「リスト内包表記」でした!
- 基本的な書き方:
[式 for 要素 in イテラブル]
- フィルタリング付き:
[式 for 要素 in イテラブル if 条件式]
- 条件分岐付き:
[Trueの式 if 条件 else Falseの式 for 要素 in イテラブル]
このPythonicなテクニックをマスターすれば、あなたのコードはよりスマートに、より効率的になるはずです。ぜひ、普段書いているfor
ループと.append()
の組み合わせを、リスト内包表記で書き換えられないか試してみてください。
ちなみに、Pythonには辞書内包表記やセット内包表記、そしてさらに高度なジェネレータ式といった仲間たちもいます。それらについては、また別の機会にお話しできればと思います!
今回のテクニック、あなたのPythonライフの時短に繋がりそうでしょうか?ぜひ感想をコメントで教えてくださいね!
コメント
コメントを投稿