概要(リスト内包表記は「作る・選ぶ・変換する」を一行で)
リスト内包表記は、for と if を“内側”に書いて、リストを一行で作る記法です。基本は「式 for 変数 in イテラブル」で、必要なら最後に「if 条件」を付けて、要素を選びながら作れます。読みやすさと速度の両面で、Pythonでは標準テクニックとして広く使われます。
# 基本形:式 for 変数 in イテラブル
squares = [x**2 for x in range(5)] # [0, 1, 4, 9, 16]
evens = [x for x in range(10) if x % 2 == 0] # 条件付きで抽出
Python基本構文と考え方(ここが重要)
変換(式)と反復(for)と選別(if)
リスト内包表記は「どの要素をどう変換して入れるか」を、見たままに書けます。式が“変換”、for が“反復”、if が“選別”の役割です。式は任意で、複雑すぎる場合は関数化して読みやすくします。
# 変換+選別:偶数だけ2倍
result = [x * 2 for x in range(10) if x % 2 == 0] # [0, 4, 8, 12, 16]
Pythonif-else を式の中に書く(“条件付き変換”)
「偶数ならA、奇数ならB」といった分岐は、if-else を“式の中”に置きます。if-else は式側に、抽出条件の if は末尾に置くのがルールです。
labels = ["even" if x % 2 == 0 else "odd" for x in range(5)]
# ['even', 'odd', 'even', 'odd', 'even']
Python可読性を保つための長さと複雑度の目安
1行が長くなりすぎる、条件や式が複雑になると可読性が落ちます。目安として“変換+1つの条件”までなら内包表記、それ以上に分岐が増えるなら通常の for や関数へ分けるのが安全です。
よく使うパターン(数値・文字列・辞書・ネスト)
数値の整形・抽出
平均や合計に直結する前処理が簡単です。
nums = [10, -5, 30, -2, 0]
nonneg = [n for n in nums if n >= 0] # 非負だけ
scaled = [n / 10 for n in nums] # スケーリング
Python文字列の前処理(トリム・大小変換・結合)
本番でも頻出の前処理を一行で。
rows = [" apple ", " ", "banana", ""]
clean = [s.strip() for s in rows if s.strip()] # トリム→非空のみ
upper = [s.upper() for s in ["a", "b", "c"]] # 大文字化
Python辞書リストのフィールド抽出・加工
APIレスポンスやCSV変換などで定番です。
products = [
{"name": "coffee", "price": 350, "qty": 2},
{"name": "tea", "price": 280, "qty": 1},
]
names = [p["name"] for p in products]
totals = [p["price"] * p["qty"] for p in products]
in_stock= [p for p in products if p["qty"] > 0]
Pythonネスト(入れ子)をフラット化・二次元処理
ネストは“左から右へ”読むと分かりやすいです。深すぎるネストは可読性を落とすため、1段までが推奨。
matrix = [[1, 2, 3], [4, 5, 6]]
flat = [x for row in matrix for x in row] # フラット化
pairs = [(r, c) for r in range(2) for c in range(3)]
Python内包表記と他の手段の使い分け(重要ポイントを深掘り)
map・filter との比較
- 単純な“関数適用”なら map が短いこともある。
- “条件で選ぶ”なら [x for x in xs if 条件] が読みやすい。
- “変換+抽出”は内包表記が一番自然に書ける。
# 変換+抽出:内包表記が素直
nums = ["10", "x", "25", "7"]
safe_ints = [int(s) for s in nums if s.isdigit()]
Python速度とメモリの感覚
内包表記は Python で最適化され、for より速いことが多いです。ただし巨大データでは“作ったリストを全部メモリに載せる”ため、必要ならジェネレータ式(丸括弧)で遅延させる選択肢も検討します。
# ジェネレータ式(遅延)を sum で消費
total = sum(int(s) for s in ["10", "20", "30"])
Python可読性ファーストの原則
- 条件が2つ以上重なる、分岐が複雑、式が長い場合は通常の for と if に戻す。
- 複雑な変換は関数化して短い式にする(testable・再利用可能)。
例題で身につける(定番から一歩先まで)
例題1:条件付きラベル付け
nums = [0, 1, 2, 3, 4]
labels = ["zero" if n == 0 else "even" if n % 2 == 0 else "odd" for n in nums]
print(labels) # ['zero', 'odd', 'even', 'odd', 'even']
Python例題2:メールの簡易検証と抽出
users = [{"name": "taro", "email": "taro@example.com"},
{"name": "hanako", "email": ""}]
valid_emails = [u["email"] for u in users if "@" in u.get("email", "")]
print(valid_emails) # ['taro@example.com']
Python例題3:ネストのフラット化と条件
matrix = [[1, 2, 3], [4, 5, 6]]
evens_flat = [x for row in matrix for x in row if x % 2 == 0]
print(evens_flat) # [2, 4, 6]
Python例題4:文字列の正規化とラベル付け
texts = [" Apples ", "TEA", " coffees"]
normalized = [t.strip().lower() for t in texts]
labels = ["plural" if s.endswith("s") else "singular" for s in normalized]
print(normalized, labels) # ['apples', 'tea', 'coffees'] ['plural', 'singular', 'plural']
Pythonまとめ
リスト内包表記は「反復・選別・変換」を一行に凝縮し、短くて読みやすいリスト生成を可能にします。式と if の置き場所(if-else は式側、抽出条件の if は末尾)を正しく理解し、複雑になりすぎたら関数化や通常の for に切り替える判断を持つこと。数値・文字列・辞書・ネストの定番パターンを身につければ、実務の前処理や抽出・整形が一気にスムーズになります。
