9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

内包表記とは

Pythonの内包表記(comprehension)は、イテラブルから新しいコレクションを簡潔に生成する構文。

これを使いこなすと、コードがものすごくスッキリする。

# forループ
squares = []
for x in range(10):
    squares.append(x**2)

# 内包表記(1行!)
squares = [x**2 for x in range(10)]

1. リスト内包表記

基本形

[ for 変数 in イテラブル]
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

条件付き(フィルタ)

[ for 変数 in イテラブル if 条件]
evens = [x for x in range(20) if x % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

if-else(三項演算子)

labels = ["偶数" if x % 2 == 0 else "奇数" for x in range(5)]
# ['偶数', '奇数', '偶数', '奇数', '偶数']

ネストしたループ

# 2重ループ
coords = [(i, j) for i in range(3) for j in range(3)]
# [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

# フラット化
nested = [[1, 2], [3, 4], [5, 6]]
flat = [x for row in nested for x in row]
# [1, 2, 3, 4, 5, 6]

2. 辞書内包表記

{キー:  for 変数 in イテラブル}
# 基本
square_dict = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# リストから辞書
names = ["alice", "bob", "charlie"]
name_lengths = {name: len(name) for name in names}
# {'alice': 5, 'bob': 3, 'charlie': 7}

# キーと値を入れ替え
original = {"a": 1, "b": 2, "c": 3}
swapped = {v: k for k, v in original.items()}
# {1: 'a', 2: 'b', 3: 'c'}

# 条件付き
scores = {"Alice": 85, "Bob": 60, "Charlie": 90}
passed = {name: score for name, score in scores.items() if score >= 70}
# {'Alice': 85, 'Charlie': 90}

3. 集合内包表記

{ for 変数 in イテラブル}
# ユニークな値のみ
unique_squares = {x**2 for x in range(-5, 6)}
# {0, 1, 4, 9, 16, 25}  ← -5²と5²は両方25で1つ

# 文字列から
text = "hello world"
unique_chars = {c for c in text if c.isalpha()}
# {'h', 'e', 'l', 'o', 'w', 'r', 'd'}

4. ジェネレータ式

( for 変数 in イテラブル)

メモリ効率が良い(遅延評価):

gen = (x**2 for x in range(10))
# <generator object <genexpr> at 0x...>

# 必要な時に値を生成
print(list(gen))  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

組み込み関数との組み合わせ

# sum, max, min
total = sum(x**2 for x in range(10))  # 285
max_val = max(len(s) for s in names)  # 7

# any, all
numbers = [2, 4, 6, 8, 10]
all(x % 2 == 0 for x in numbers)  # True(全て偶数)
any(x > 5 for x in numbers)       # True(5より大きいのがある)

5. 実践的な例

ログのフィルタリング

log_lines = [
    "2025-01-01 ERROR: Connection failed",
    "2025-01-01 INFO: Started",
    "2025-01-02 ERROR: Timeout",
]
errors = [line for line in log_lines if "ERROR" in line]
# ['2025-01-01 ERROR: Connection failed', '2025-01-02 ERROR: Timeout']

JSONデータの変換

users = [
    {"name": "Alice", "age": 30, "active": True},
    {"name": "Bob", "age": 25, "active": False},
    {"name": "Charlie", "age": 35, "active": True},
]
active_users = [u["name"] for u in users if u["active"]]
# ['Alice', 'Charlie']

行列の転置

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transposed = [[row[i] for row in matrix] for i in range(len(matrix[0]))]
# [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

6. walrus演算子との組み合わせ(3.8+)

:=(セイウチ演算子)で計算結果を再利用:

import re

texts = ["abc123", "hello", "world456", "test"]

# マッチしたものだけを取得
matched = [m.group() for t in texts if (m := re.search(r'\d+', t))]
# ['123', '456']

7. パフォーマンス

内包表記: 0.0515秒
forループ: 0.0852秒
map:       0.0678秒

内包表記はforループより約1.7倍高速!

理由:

  • ループのオーバーヘッドが少ない
  • appendメソッド呼び出しがない

8. アンチパターン

❌ 複雑すぎる内包表記

# 読みにくい!
result = [x.strip().lower() for x in data 
          if x and len(x.strip()) > 3 and x[0].isalpha()]

✓ 関数に分割

def is_valid(x):
    x = x.strip()
    return x and len(x) > 3 and x[0].isalpha()

def transform(x):
    return x.strip().lower()

result = [transform(x) for x in data if is_valid(x)]

❌ 副作用のある内包表記

# 副作用は避ける
results = [process_and_save(x) for x in items]  # ❌

✓ forループを使う

for x in items:
    process_and_save(x)  # ✓

まとめ

種類 構文 結果
リスト [x for x in iter] list
辞書 {k: v for k, v in iter} dict
集合 {x for x in iter} set
ジェネレータ (x for x in iter) generator

使い分け:

  • 結果を複数回使う → リスト
  • キーと値のペア → 辞書
  • ユニークな値 → 集合
  • メモリ節約 → ジェネレータ

内包表記を適切に使って、Pythonicなコードを書きましょう!

9
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?