リスト内包表記(List Comprehension)は、ループ処理を使ったリストの作成を1行で簡潔に書けるPythonの強力な構文です。可読性が高く、実行速度もfor文より速いため、Pythonらしいコードを書くために必須の知識です。
この記事では、リスト内包表記の基本から、条件付き、ネスト、辞書・集合内包表記まで詳しく解説します。
基本的な使い方
リスト内包表記の基本構文は [式 for 変数 in イテラブル] です。
Python
# 通常のfor文
squares = []
for i in range(1, 6):
squares.append(i ** 2)
print(squares)
# リスト内包表記(同じ結果)
squares = [i ** 2 for i in range(1, 6)]
print(squares)
# 文字列に適用
names = ["taro", "hanako", "jiro"]
upper_names = [name.upper() for name in names]
print(upper_names)
実行結果
[1, 4, 9, 16, 25]
[1, 4, 9, 16, 25]
['TARO', 'HANAKO', 'JIRO']
条件付きリスト内包表記
ifを追加して、条件を満たす要素のみをリストに含めることができます。
Python
# 偶数のみ抽出
evens = [i for i in range(10) if i % 2 == 0]
print(evens)
# 条件に合う要素をフィルタリング
scores = [85, 42, 91, 67, 73, 55, 88]
passed = [s for s in scores if s >= 70]
print(f"合格: {passed}")
# if-elseで値を変換
results = ["合格" if s >= 70 else "不合格" for s in scores]
print(results)
実行結果
[0, 2, 4, 6, 8]
合格: [85, 91, 73, 88]
['合格', '不合格', '合格', '不合格', '合格', '不合格', '合格']
ifの位置に注意
フィルタリング(要素の選別)は [式 for x in リスト if 条件](後置if)、値の変換は [値A if 条件 else 値B for x in リスト](前置if-else)です。位置が異なるので注意しましょう。
ネスト(二重ループ)
Python
# 二重ループの内包表記
pairs = [(x, y) for x in range(1, 4) for y in range(1, 4)]
print(pairs)
# 二次元リストを一次元に変換(フラット化)
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
print(flat)
実行結果
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
辞書・集合の内包表記
リストだけでなく、辞書や集合も内包表記で作成できます。
Python
# 辞書内包表記
squares_dict = {x: x**2 for x in range(1, 6)}
print(squares_dict)
# キーと値を入れ替え
original = {"a": 1, "b": 2, "c": 3}
swapped = {v: k for k, v in original.items()}
print(swapped)
# 集合内包表記
words = ["hello", "world", "hello", "python"]
unique_lengths = {len(w) for w in words}
print(unique_lengths)
実行結果
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
{1: 'a', 2: 'b', 3: 'c'}
{5, 6}
実践的な使い方
Python
# ファイル名のフィルタリング
files = ["report.pdf", "data.csv", "image.png", "notes.txt", "chart.csv"]
csv_files = [f for f in files if f.endswith(".csv")]
print(f"CSVファイル: {csv_files}")
# 数値データの変換
raw_data = ["10", "20", "abc", "30", "xyz", "40"]
numbers = [int(x) for x in raw_data if x.isdigit()]
print(f"数値データ: {numbers}")
print(f"合計: {sum(numbers)}")
# 文字列のクリーンアップ
emails = [" Taro@Test.com ", "HANAKO@test.COM ", " jiro@TEST.com"]
cleaned = [e.strip().lower() for e in emails]
print(f"整形済み: {cleaned}")
実行結果
CSVファイル: ['data.csv', 'chart.csv']
数値データ: [10, 20, 30, 40]
合計: 100
整形済み: ['taro@test.com', 'hanako@test.com', 'jiro@test.com']
複雑すぎる内包表記は避ける
内包表記が3重以上のネストになったり、条件が複雑になりすぎる場合は、通常のfor文を使った方が読みやすくなります。「1行で書けること」よりも「読みやすいこと」を優先しましょう。
まとめ
[式 for 変数 in イテラブル]でリストを簡潔に作成できるifを追加してフィルタリングが可能- 辞書内包表記
{k: v for ...}、集合内包表記{x for ...}もある - for文より実行速度が速く、Pythonらしいコード
- 複雑すぎる場合は通常のfor文を使う方が読みやすい