Pythonのリスト内包表記入門!for文との書き換え・if条件・辞書内包表記まで実例で解説
「Pythonのコードを読んでいたら [x * 2 for x in nums] みたいな1行が出てきて、何をしているのか分からない…」
「for文で書けるのに、わざわざ1行にする意味ってあるの?」
Pythonを学び始めてしばらくすると、こんな疑問にぶつかりますよね。
この書き方は リスト内包表記(list comprehension) と呼ばれる、Pythonらしさが詰まった文法です。最初は暗号のように見えますが、「for文の書き換え」だと分かれば、すぐに読めるようになります。
この記事は、for文・if文・リストの基本が分かるPython初心者〜初級者向けです。for文と並べて比べながら、一緒に見ていきましょう!😊
リスト内包表記ってどんなもの?

ざっくり言うと、「空のリストを用意して、for文で1つずつ append する」処理を1行で書く方法です。
形はこうなっています。
[式 for 変数 in リスト]… 全部の要素を「式」で変換して新しいリストを作る[式 for 変数 in リスト if 条件]… 条件に合う要素だけを残す
イメージとしては、「リストの各要素を、ベルトコンベアに乗せて加工し、新しい箱に詰め直す」感じです。元のリストは変わらず、新しいリストができあがります。
for文と内包表記を並べて比べてみよう
テストの点数リストを使って、「全員に5点加算」「合格点だけ取り出す」「合格・再試験の判定」の3つをやってみます。
# テストの点数リスト
scores = [72, 45, 88, 91, 60, 38, 79]
# --- for文で書いた場合 ---
bonus_for = []
for s in scores:
bonus_for.append(s + 5)
# --- リスト内包表記で書いた場合(1行!) ---
bonus = [s + 5 for s in scores]
print("5点加算:", bonus)
print("for文と同じ結果?", bonus == bonus_for)
# 条件で絞り込む(60点以上だけ残す)
passed = [s for s in scores if s >= 60]
print("合格点だけ:", passed)
# 値を変換する(60点以上は「合格」、それ以外は「再試験」)
results = ["合格" if s >= 60 else "再試験" for s in scores]
print("判定:", results)

実行すると、上の画像のように表示されます。for文で4行かかっていた処理が、内包表記では1行になり、結果もまったく同じ(True)ですね。
ポイントをまとめるとこんな感じです👇
[s + 5 for s in scores]:先頭のs + 5が「新しいリストに入れる値」、後ろのfor s in scoresがいつものfor文[s for s in scores if s >= 60]:後ろに付けた if は「絞り込み」。条件に合わない要素はリストに入らない(7個 → 5個に減っています)["合格" if s >= 60 else "再試験" for s in scores]:前に書いた if〜else は「値の切り替え」。要素の数は変わらない(7個のまま)
⚠️ if の位置で意味が変わる(よくあるエラー)
ここが一番つまずきやすいポイントです。
「60点未満は0にしたい」と思って [s for s in scores if s >= 60 else 0] と書くと、実際に試したところ SyntaxError: invalid syntax になりました。
後ろの if は「絞り込み」専用なので、else は付けられないんです。値を切り替えたいときは、if〜else を for の前に移動して [s if s >= 60 else 0 for s in scores] と書きます。
- 要素を減らしたい → if は 後ろ(else なし)
- 要素の値を変えたい → if〜else は 前
この2つを覚えておくだけで、内包表記のエラーの多くは防げますよ。
辞書・集合・2重ループにも使える
内包表記はリストだけのものではありません。{} で囲むと 辞書内包表記 や 集合内包表記 になります。2重ループも書けます。
names = ["佐藤", "鈴木", "高橋", "田中"]
scores = [72, 45, 88, 91]
# 辞書内包表記:名前→点数の辞書を作る
score_dict = {name: score for name, score in zip(names, scores)}
print("辞書:", score_dict)
# 辞書から条件に合う人だけ取り出す
top = {name: s for name, s in score_dict.items() if s >= 80}
print("80点以上:", top)
# 集合内包表記:重複を除いた「十の位」
tens = {s // 10 * 10 for s in [72, 45, 88, 91, 60, 38, 79, 75]}
print("点数帯:", sorted(tens))
# 2重ループ:九九の表の一部を2次元リストで作る
table = [[i * j for j in range(1, 4)] for i in range(1, 4)]
print("2次元リスト:", table)
# 2次元リストを平らにする(forを2つ並べる)
flat = [x for row in table for x in row]
print("平らにすると:", flat)

実行すると、上の画像のようになります。
ここが重要です👇
{キー: 値 for ...}のようにコロンがあると辞書、{式 for ...}のようにコロンがないと集合になるzip()と組み合わせると、2つのリストから一気に辞書が作れる- 辞書から絞り込むときは
.items()でキーと値を一緒に取り出す - 集合は重複が自動で消えます。8個の点数から「点数帯」が6種類だけ残りました(集合は順番を持たないので、表示前に
sorted()で並べています) [x for row in table for x in row]の2重ループは、for を「普通のfor文を書くときと同じ順番」で左から並べるのがコツ
これ、実行せずに答えられますか? [[i * j for j in range(1, 4)] for i in range(1, 4)] は、内側の [...] が1行分のリストを作り、それを外側のforで3回くり返しています。だから結果は3×3の2次元リストになるわけです。
内包表記は速い?実際に測ってみた
「内包表記のほうが速い」とよく言われるので、標準ライブラリの timeit で実際に測ってみました。
import timeit
def use_for():
result = []
for i in range(10000):
result.append(i * 2)
return result
def use_comp():
return [i * 2 for i in range(10000)]
# それぞれ1000回実行して時間を測る
t_for = timeit.timeit(use_for, number=1000)
t_comp = timeit.timeit(use_comp, number=1000)
print(f"for文 + append : {t_for:.3f} 秒")
print(f"リスト内包表記 : {t_comp:.3f} 秒")
print(f"内包表記は約 {t_for / t_comp:.1f} 倍速い")
筆者の環境(Windows・Python 3.13)で実行したところ、for文+append が 0.248秒、リスト内包表記が 0.192秒 で、内包表記のほうが約1.3倍速いという結果になりました。何度か実行すると数値は少しぶれますが、内包表記がわずかに速い傾向は同じでした。
速くなるのは、for文版が毎回 result.append というメソッドを探して呼び出しているのに対し、内包表記はリストに要素を追加する処理がPython内部で最適化されているためです。
ただし、差は「劇的」というほどではありません。内包表記を使う一番の理由は、速さよりも「短くて読みやすいこと」だと考えておくのがよいと思います。
使いすぎに注意!for文に戻したほうがいい場面
便利な内包表記ですが、何でも1行に詰め込むと逆に読みにくくなります。次のようなときは、素直にfor文で書くのがおすすめです。
- forが3つ以上ネストするとき(2つまでが目安)
- if〜else が入り組んで、1行が画面からはみ出すとき
print()やファイル保存など、リストを作ることが目的ではない処理をくり返すとき([print(x) for x in nums]は不要なリストを作るだけなので、for文で書きましょう)
「内包表記は新しいリスト(辞書・集合)を作るための道具」と覚えておくと、使いどころを迷わなくなりますよ。
まとめ
- リスト内包表記は、「空リスト+for+append」を1行で書くPythonの文法
- 後ろの
ifは絞り込み、前のif〜elseは値の切り替え。逆に書くと SyntaxError {k: v for ...}で辞書、{x for ...}で集合も作れる。2重ループは for を左から順に並べる- for文より少し速いが、一番のメリットは短く読みやすいこと。複雑になったらfor文に戻す
「むずかしそう」に見えていた1行も、for文に分解して読めば怖くありません。まずは自分が書いたfor文を1つ、内包表記に書き換えるところから、ぜひ試してみてください🚀
\ 読んだら、次は自分で作ってみよう /
筆者が運営する無料の入門コース「作って学ぶPythonプログラミング入門」では、こうした基本文法を、割り勘計算機・おみくじ・数当てゲームなどを作りながら身につけます。各章末の定着ドリル(全42問)で、自分の手で書く練習まで。最初の4レッスンは登録なしで読めます。
こちらも読まれています
📚 関連商品・おすすめ書籍
※本記事にはアフィリエイトリンクが含まれます。






