順番に読み進めながら学べます

リスト内包表記と辞書・集合・ジェネレーター式 — 1 行でコレクションを作る

Python のリスト内包表記を基礎から解説します。for を 1 行に圧縮する書き方から辞書・集合・ジェネレーター式まで図解で押さえます。

前回all() / any() ではコレクションをまとめて判定する方法を見ました。今回は、コレクションそのものを 1 行で作るための強力な構文、内包表記(comprehension)を整理します。

リスト内包表記を中心に、if でフィルタする書き方、辞書集合を作るバリエーション、そしてメモリを節約するジェネレーター式まで扱います。

リスト内包表記の基本 — for を 1 行に圧縮

Python では、リストを 1 行で作る [式 for 変数 in 反復可能オブジェクト] という書き方があります。これをリスト内包表記と呼びます。

空リストに append() を繰り返す for ループの短縮形で、リスト全要素に同じ変換をかけて新しいリストを作りたい場面で重宝します。

リスト内包表記の流れ
items =[10, 20, 30][x * 2for x in items][20, 40, 60]各要素に 式を適用新しい list

[式 for 変数 in 反復可能] は、各要素を式で変換した新しいリストを作ります。for ループで append する書き方の 1 行版です。

# for ループでの書き方
result = []
for price in [100, 250, 480]:
    result.append(int(price * 1.1))
print(result)   # [110, 275, 528]

# 同じ処理をリスト内包表記で
prices = [100, 250, 480]
tax_included = [int(p * 1.1) for p in prices]
print(tax_included)   # [110, 275, 528]

# 文字列の長さを集めるのも 1 行
names = ["Alice", "Bob", "Charlotte"]
lengths = [len(n) for n in names]
print(lengths)   # [5, 3, 9]

商品価格のリストに消費税 10%を加えた新しいリストを、リスト内包表記で作ります。

prices = [100, 250, 480, 1200] を宣言してください。

② リスト内包表記 [int(p * 1.1) for p in prices] で税込価格のリストを作り、変数 tax_included に代入してください。

print(tax_included) で結果を表示してください。

(正しく実行できれば解説が表示されます)

Python エディタ

コードを実行してください

if でフィルタする条件付き内包表記

for の後ろに if 条件 を加えると、条件を満たす要素だけを新しいリストに残せます。[式 for 変数 in 反復可能 if 条件] の形です。

変換とフィルタが 1 行で書けるのがリスト内包表記の強みで、「特定の条件を満たすデータだけを取り出す」処理を簡潔に表現できます。

条件付き内包表記が要素を 1 つずつ判定する流れ
forの中の処理prices =[80, 250, 120, 480][p for p in pricesif p >= 200]結果[250, 480]p = 8080 >= 200False→ 除外p = 250250 >= 200True→ 採用p = 120120 >= 200False→ 除外p = 480480 >= 200True→ 採用適用完成
リストの各要素を順に取り出し、if p >= 200 で 1 件ずつ判定する。True の要素(採用)だけが新しいリストに残り、False の要素(除外)は捨てられる。
# 200 円以上だけ抜き出す
prices = [80, 250, 120, 480, 95]
premium = [p for p in prices if p >= 200]
print(premium)         # [250, 480]

# フィルタ + 変換を同時に
discounted = [int(p * 0.9) for p in prices if p >= 200]
print(discounted)      # [225, 432]   ← 200 円以上だけ 10% オフ

# 文字列の絞り込み + 変換
names = ["Alice", "Bob", "Charlotte", "Ed"]
long_names = [n.upper() for n in names if len(n) >= 5]
print(long_names)      # ['ALICE', 'CHARLOTTE']

在庫データから在庫数が 1 以上の商品名だけを取り出します。

stocks = [("apple", 12), ("banana", 0), ("orange", 5), ("grape", 0), ("kiwi", 3)] を宣言してください。

[name for name, count in stocks if count > 0] で在庫がある商品名のリストを作り、available に代入してください(タプルのアンパックで namecount を同時に受け取ります)。

print(available) で結果を表示してください。

Python エディタ

コードを実行してください

辞書内包表記と集合内包表記

リスト内包表記の角括弧 [ ]波括弧 { } に変えると集合(set)内包表記になります。

さらに {キー: 値 for ...} のように : を挟むと辞書(dict)内包表記です。for ... in ... の文法はそのままに、出力するコレクションの形だけを切り替えられるのが内包表記の便利なところです。

辞書内包表記の流れ
pairs =[("apple", 120), ("orange", 80)]{name: pricefor name, pricein pairs}{"apple": 120, "orange": 80}アンパック新しい dict

{キー: 値 for ...} の形でペアの辞書を作れます。商品名と価格のリストから「名前 → 価格」の lookup を 1 行で構築できます。

# 辞書内包表記: 商品名 → 価格 の lookup を作る
pairs = [("apple", 120), ("orange", 80), ("banana", 60)]
price_lookup = {name: price for name, price in pairs}
print(price_lookup)
# {'apple': 120, 'orange': 80, 'banana': 60}

# 既存の dict から「税込価格」の dict を作り直す
tax_included = {name: int(price * 1.1) for name, price in pairs}
print(tax_included)
# {'apple': 132, 'orange': 88, 'banana': 66}

# 集合内包表記: 重複なしのユニークなタグを取り出す
tags = ["sale", "new", "sale", "limited", "new"]
unique = {t for t in tags}
print(unique)   # {'sale', 'new', 'limited'}(順序は実行時依存)

辞書の組み立てに zip() も合わせて使える

2 つのリスト namesprices を組み合わせて辞書を作るときは、{n: p for n, p in zip(names, prices)} のように zip() と一緒に使うと簡潔です。zip() で複数のリストを並走させながら、辞書のキーと値を同時に組み立てられます。

商品名と価格のペアから、商品名 → 税込価格の辞書を 1 行で作ります。

pairs = [("apple", 120), ("orange", 80), ("banana", 60), ("kiwi", 200)] を宣言してください。

② 辞書内包表記 {name: int(price * 1.1) for name, price in pairs} で税込価格の lookup を作り、tax_lookup に代入してください。

print(tax_lookup) で結果を表示してください。

Python エディタ

コードを実行してください

ジェネレーター式 — 角括弧を丸括弧に

リスト内包表記の角括弧 [ ]丸括弧 ( ) に変えると、ジェネレーター式になります。リストのように全件をメモリに作らず、必要になった分だけ計算する遅延評価の仕組みです。

sum() / max() / min() / any() などにそのまま渡せて、巨大なデータの集計でメモリ消費を抑えられます。詳細は後のジェネレーター関数の記事で扱います。

構文結果の型特徴
[x for x in items]list全件をメモリに保持
{x for x in items}set重複なし・全件保持
{k: v for k, v in items}dictキー: 値の対応・全件保持
(x for x in items)generator現在の 1 件のみ・遅延評価
# 丸括弧でジェネレーター式
prices = [100, 250, 480, 1200]
gen = (int(p * 1.1) for p in prices)
print(type(gen))   # <class 'generator'>

# sum() に直接渡せる(外側の () は省略可)
total_tax = sum(int(p * 1.1) for p in prices)
print(total_tax)   # 2233

# max() / min() でも同様
max_tax = max(int(p * 1.1) for p in prices)
print(max_tax)     # 1320

「全件まとめて使う?1 件ずつ流す?」で選ぶ

全件をリストとして手元に置きたいなら [ ](リスト内包表記)。sum() / max() などに渡して集計するだけなら ( )(ジェネレーター式)の方がメモリに優しい選択です。100 万件規模だと差が顕著で、ジェネレーター式は数百バイトしか使いません。

商品価格のリストに対して、ジェネレーター式と sum() を組み合わせて税込価格の合計を求めます。

prices = [100, 250, 480, 1200] を宣言してください。

sum(int(p * 1.1) for p in prices) で税込合計を計算し、total に代入してください(sum() の括弧の中に直接ジェネレーター式を書けます)。

print(total) で結果を表示してください。

Python エディタ

コードを実行してください
QUIZ

理解度チェック

まずは1問ずつ答えてみましょう。

Q1次のコードを実行したときの出力はどれですか?
nums = [1, 2, 3, 4]
result = [n * 10 for n in nums]
print(result)

Q2次のコードを実行したときの出力はどれですか?
nums = [1, 2, 3, 4, 5]
result = [n for n in nums if n % 2 == 0]
print(result)

Q3次のうち辞書を作るのはどれですか?