💡 この記事でわかること
- 内包表記とは何か、for文とどう対応しているのか
- リスト内包表記の基本形
[式 for 変数 in 範囲]の書き方 - 後ろの
if(絞り込み)と、前のif-else(値の振り分け)の違い - 辞書内包表記・セット内包表記の書き方
- 内包表記を使うか、普通のfor文に戻すかの判断基準
1. 内包表記とは?
内包表記とは、
👉 for文で作るような「リストなどの繰り返し処理」を、短い1行で書ける書き方です。
💡 「リストの各要素を加工して、新しいリストを作る」という処理はプログラムで何度も登場します。内包表記を使うと、その定番パターンを短く読みやすく書けます。もっともよく使うのがリスト内包表記なので、この記事でも中心に解説します。
2. 基本の書き方(for文と比べる)
まず、0〜4をそれぞれ2倍したリストを、これまで習ったfor文で作ってみます。
numbers = []
for i in range(5):
numbers.append(i * 2)
print(numbers) # [0, 2, 4, 6, 8]これをリスト内包表記で書くと、次の1行になります。
numbers = [i * 2 for i in range(5)]
print(numbers) # [0, 2, 4, 6, 8]👉 [ ] の中に「式 for 変数 in 繰り返すもの」と書きます。先頭の i * 2 が「各要素をどう加工するか」、for i in range(5) が「何を繰り返すか」を表します。
- 基本形は
[式 for 変数 in 範囲] - 先頭の「式」が、新しいリストに入る値になる
- 空のリストを用意して
appendする、という書き方が不要になる
👉 Pythonのif文・for文・while文についての記事はこちら
3. if で要素を絞り込む
末尾に if 条件 を付けると、条件に合う要素だけを残せます。
nums = [1, 2, 3, 4, 5, 6]
evens = [n for n in nums if n % 2 == 0]
print(evens) # [2, 4, 6]💡 「for 〜 in 〜」のあとに「if 条件」を書くと、条件が True の要素だけが新しいリストに入ります。これは、for文の中に if を書くのと同じ意味です。
# 上の内包表記と同じ処理を for文で書いた場合
evens = []
for n in nums:
if n % 2 == 0:
evens.append(n)「正の数だけ残す」「空文字を除く」といったフィルタの処理でよく使います。
values = [10, -3, 0, 7, -1]
positives = [v for v in values if v > 0]
print(positives) # [10, 7]4. if-else で値を振り分ける
「条件によって値そのものを変えたい」ときは、if と else を式の側(先頭)に書きます。3で出てきた「絞り込みの if」とは位置が違うので注意してください。
scores = [80, 45, 60, 30, 95]
results = ["合格" if s >= 60 else "不合格" for s in scores]
print(results) # ['合格', '不合格', '合格', '不合格', '合格']👉 使い分けの目安:
- 要素を減らしたい(フィルタ) →
[x for x in 範囲 if 条件](ifは後ろ) - 要素の数はそのままで値を変えたい →
[a if 条件 else b for x in 範囲](if-elseは前)
💡 「後ろの if」は要素を残すかどうかの判定、「前の if-else」はどんな値を入れるかの選択、と覚えると混乱しにくいです。
5. 文字列やメソッドと組み合わせる
先頭の「式」の部分には、メソッド呼び出しやf-stringなど、値を返す処理を自由に書けます。
words = [" apple ", "Banana", " CHERRY"]
# 前後の空白を消して、小文字にそろえる
cleaned = [w.strip().lower() for w in words]
print(cleaned) # ['apple', 'banana', 'cherry']names = ["太郎", "花子", "次郎"]
labels = [f"{name}さん" for name in names]
print(labels) # ['太郎さん', '花子さん', '次郎さん']💡 「辞書のリスト」から、特定のキーの値だけを取り出すのもよくある使い方です。
users = [
{"name": "太郎", "age": 20},
{"name": "花子", "age": 25},
]
ages = [u["age"] for u in users]
print(ages) # [20, 25]6. 辞書内包表記・セット内包表記
同じ書き方は、{ } を使うことで辞書やセットにも応用できます。
# 辞書内包表記:{キー: 値 for 変数 in 範囲}
squares = {n: n ** 2 for n in range(1, 6)}
print(squares) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# セット内包表記:{式 for 変数 in 範囲}(重複は自動で消える)
words = ["a", "b", "a", "c", "b"]
unique = {w for w in words}
print(unique) # {'a', 'b', 'c'}(順序は不定)👉 { } の中を「キー: 値」の形にすれば辞書内包表記、値だけにすればセット内包表記になります。
💡 丸カッコ ( ) で囲んだ場合はタプルにはならず、「ジェネレータ式」という別のものになります。タプルが欲しいときは tuple(x for x in 範囲) のように書きます。まずは名前だけ知っておけば十分です。
7. 2重ループを内包表記で書く
pairs = [(x, y) for x in [1, 2] for y in ["a", "b"]]
print(pairs) # [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]👉 for を2つ並べると、外側の for から順にネストしたループになります。上の例は、for文だと次と同じ意味です。
pairs = []
for x in [1, 2]:
for y in ["a", "b"]:
pairs.append((x, y))💡 2重までは読めますが、3重以上になったり条件が増えたりすると一気に読みにくくなります。その場合は無理をせず、普通のfor文で書きましょう。
8. 内包表記を使うか、for文に戻すかの判断
内包表記は短く書ける反面、詰め込みすぎると「何をしているのか」が読み取りにくくなります。次のような場合は、普通のfor文の方が分かりやすいことが多いです。
- 1行が長くなり、横スクロールしないと読めない
forやifが3つ以上並んでいる- 加工の式が複雑(
if-elseが入れ子になっているなど) - ループの途中で
printやファイル書き込みなど「処理そのもの」をしたい
👉 内包表記は「新しいリスト(辞書・セット)を作ること」が目的のときに使うのが基本です。「ただ繰り返し処理をしたいだけ」なら、無理に内包表記にせず普通のfor文で書きます。
💡 迷ったときは「あとから読み返してすぐ理解できるか」で決めると失敗しにくいです。
9. 内包表記 早見表
| やりたいこと | 書き方 |
|---|---|
| リストを加工して新しいリストを作る | [式 for x in 範囲] |
| 条件で絞り込む(フィルタ) | [x for x in 範囲 if 条件] |
| 条件で値を振り分ける | [a if 条件 else b for x in 範囲] |
| 辞書を作る | {キー: 値 for x in 範囲} |
| セットを作る(重複なし) | {式 for x in 範囲} |
| 2重ループ | [式 for x in A for y in B] |
10. まとめ
- 内包表記は、for文で作る「新しいリスト」を1行で書ける書き方
- 基本形は
[式 for 変数 in 範囲]。先頭の「式」が新しい要素になる - 後ろの
ifは絞り込み、前のif-elseは値の振り分け { }を使えば辞書内包表記・セット内包表記になる- 読みにくくなったら、迷わず普通のfor文に戻す
👉 まずは「for文で書いた append のループを内包表記に書き換える」練習から始めるのがおすすめです。慣れると、自分のコードも他の人のコードもぐっと読みやすくなります。