「pythonのコードでよく見る [x for x in ...]
って何?」
「for文をもっと短く書けるって聞いたけど…」
「内包表記って難しそう」
そんな疑問を解決するために、今回はpythonの内包表記について、初心者の方でも理解できるように詳しく説明していきます。
内包表記とは?従来の書き方と比較してみよう

従来のfor文での書き方
まず、普通のfor文でリストを作る方法を見てみましょう。
# 1から5までの数字を2乗したリストを作る
squares = []
for x in range(1, 6):
squares.append(x ** 2)
print(squares) # [1, 4, 9, 16, 25]
内包表記での書き方
同じことを内包表記で書くと:
# 内包表記なら1行で完了!
squares = [x ** 2 for x in range(1, 6)]
print(squares) # [1, 4, 9, 16, 25]
とてもシンプルになりました!
内包表記のメリット
内包表記の利点:
・コードが短くなる
・読みやすい(慣れれば)
・実行速度が速い
・Pythonらしい書き方
・一行で複雑な処理も可能
リスト内包表記の基本

基本的な構文
[式 for 変数 in イテラブル]
- 式:各要素に対して実行する処理
- 変数:イテラブルから取り出した各要素
- イテラブル:リスト、range、文字列など
様々な例で理解を深めよう
# 例1:数値を10倍する
numbers = [1, 2, 3, 4, 5]
multiplied = [x * 10 for x in numbers]
print(multiplied) # [10, 20, 30, 40, 50]
# 例2:文字列を大文字に変換
words = ["hello", "world", "python"]
upper_words = [word.upper() for word in words]
print(upper_words) # ['HELLO', 'WORLD', 'PYTHON']
# 例3:文字列の長さを取得
lengths = [len(word) for word in words]
print(lengths) # [5, 5, 6]
# 例4:rangeを使った数列生成
even_numbers = [x * 2 for x in range(5)]
print(even_numbers) # [0, 2, 4, 6, 8]
より複雑な処理
# 文字列の処理
names = ["田中太郎", "佐藤花子", "山田次郎"]
formatted_names = [f"Mr./Ms. {name}" for name in names]
print(formatted_names)
# ['Mr./Ms. 田中太郎', 'Mr./Ms. 佐藤花子', 'Mr./Ms. 山田次郎']
# 数学的な処理
import math
angles = [0, 30, 45, 60, 90]
radians = [math.radians(angle) for angle in angles]
print(radians)
# [0.0, 0.5235987755982988, 0.7853981633974483, 1.0471975511965976, 1.5707963267948966]
# メソッドチェーン
texts = [" Hello ", " World ", " Python "]
cleaned = [text.strip().lower() for text in texts]
print(cleaned) # ['hello', 'world', 'python']
条件付き内包表記
if文で要素をフィルタリング
特定の条件を満たす要素だけを抽出できます。
# 基本構文
[式 for 変数 in イテラブル if 条件]
実用例
# 偶数だけを抽出
numbers = range(10)
even_numbers = [x for x in numbers if x % 2 == 0]
print(even_numbers) # [0, 2, 4, 6, 8]
# 奇数だけを抽出
odd_numbers = [x for x in numbers if x % 2 == 1]
print(odd_numbers) # [1, 3, 5, 7, 9]
# 文字列の長さでフィルタリング
words = ["cat", "elephant", "dog", "hippopotamus", "rat"]
long_words = [word for word in words if len(word) > 3]
print(long_words) # ['elephant', 'hippopotamus']
# 正の数だけを抽出
numbers = [-3, -1, 0, 2, 5, -2, 8]
positive_numbers = [x for x in numbers if x > 0]
print(positive_numbers) # [2, 5, 8]
条件分岐(三項演算子)を使った変換
# 基本構文
[式1 if 条件 else 式2 for 変数 in イテラブル]
実用例
# 偶数は"偶数"、奇数は"奇数"のラベルを付ける
numbers = range(6)
labels = ["偶数" if x % 2 == 0 else "奇数" for x in numbers]
print(labels) # ['偶数', '奇数', '偶数', '奇数', '偶数', '奇数']
# 正負の判定
numbers = [-2, -1, 0, 1, 2]
signs = ["負" if x < 0 else "零" if x == 0 else "正" for x in numbers]
print(signs) # ['負', '負', '零', '正', '正']
# 成績判定
scores = [85, 92, 78, 65, 96]
grades = ["合格" if score >= 80 else "不合格" for score in scores]
print(grades) # ['合格', '合格', '不合格', '不合格', '合格']
# 価格の割引適用
prices = [1000, 1500, 800, 2000]
discounted_prices = [price * 0.8 if price > 1000 else price for price in prices]
print(discounted_prices) # [1000, 1200.0, 800, 1600.0]
複数の条件を組み合わせ
# AND条件
numbers = range(20)
result = [x for x in numbers if x % 2 == 0 and x > 10]
print(result) # [12, 14, 16, 18]
# OR条件
result = [x for x in numbers if x < 3 or x > 17]
print(result) # [0, 1, 2, 18, 19]
# 複雑な条件
words = ["apple", "banana", "grape", "orange", "kiwi"]
result = [word.upper() for word in words if len(word) > 4 and "a" in word]
print(result) # ['APPLE', 'BANANA', 'GRAPE', 'ORANGE']
辞書内包表記

基本的な辞書内包表記
# 基本構文
{キー: 値 for 変数 in イテラブル}
実用例
# 数字とその2乗の辞書
squares_dict = {x: x ** 2 for x in range(1, 6)}
print(squares_dict) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# 単語とその長さの辞書
words = ["apple", "banana", "cherry"]
word_lengths = {word: len(word) for word in words}
print(word_lengths) # {'apple': 5, 'banana': 6, 'cherry': 6}
# 学生の成績辞書
students = ["太郎", "花子", "次郎"]
scores = [85, 92, 78]
grade_dict = {student: score for student, score in zip(students, scores)}
print(grade_dict) # {'太郎': 85, '花子': 92, '次郎': 78}
条件付き辞書内包表記
# 合格者のみの辞書
students_scores = {"太郎": 85, "花子": 92, "次郎": 65, "美香": 78}
passed_students = {name: score for name, score in students_scores.items() if score >= 80}
print(passed_students) # {'太郎': 85, '花子': 92}
# 値の変換を含む辞書
temperatures_c = {"東京": 25, "大阪": 28, "札幌": 20}
temperatures_f = {city: (temp * 9/5) + 32 for city, temp in temperatures_c.items()}
print(temperatures_f) # {'東京': 77.0, '大阪': 82.4, '札幌': 68.0}
既存辞書の変換
# キーと値を入れ替え
original = {"a": 1, "b": 2, "c": 3}
swapped = {value: key for key, value in original.items()}
print(swapped) # {1: 'a', 2: 'b', 3: 'c'}
# 辞書の値を変換
prices = {"apple": 100, "banana": 80, "orange": 120}
# 税込価格(10%)に変換
tax_included = {item: int(price * 1.1) for item, price in prices.items()}
print(tax_included) # {'apple': 110, 'banana': 88, 'orange': 132}
集合内包表記
基本的な集合内包表記
# 基本構文
{式 for 変数 in イテラブル}
実用例
# 重複を除去した平方数
numbers = [1, 2, 2, 3, 3, 4, 5]
unique_squares = {x ** 2 for x in numbers}
print(unique_squares) # {1, 4, 9, 16, 25}
# 文字列の長さ(重複なし)
words = ["apple", "banana", "grape", "kiwi", "mango"]
unique_lengths = {len(word) for word in words}
print(unique_lengths) # {4, 5, 6}
# 文字列に含まれる文字の種類
text = "hello world"
unique_chars = {char for char in text if char != " "}
print(unique_chars) # {'e', 'h', 'l', 'o', 'r', 'w', 'd'}
ネストした内包表記

2次元リストの処理
# 2次元リストの平坦化
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 条件付きの平坦化
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
even_numbers = [num for row in matrix for num in row if num % 2 == 0]
print(even_numbers) # [2, 4, 6, 8]
# 2次元リストの作成
multiplication_table = [[i * j for j in range(1, 4)] for i in range(1, 4)]
print(multiplication_table) # [[1, 2, 3], [2, 4, 6], [3, 6, 9]]
座標の生成
# 座標ペアの生成
coordinates = [(x, y) for x in range(3) for y in range(3)]
print(coordinates)
# [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
# 条件付き座標生成
coordinates = [(x, y) for x in range(5) for y in range(5) if x + y <= 3]
print(coordinates)
# [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (3, 0)]
実践的な活用例
データ処理での活用
# CSVデータの処理(想定)
data = [
["太郎", "25", "男性"],
["花子", "30", "女性"],
["次郎", "35", "男性"]
]
# 辞書のリストに変換
headers = ["名前", "年齢", "性別"]
people = [{headers[i]: row[i] for i in range(len(headers))} for row in data]
print(people)
# [{'名前': '太郎', '年齢': '25', '性別': '男性'}, ...]
# 特定条件でフィルタリング
adults = [person for person in people if int(person["年齢"]) >= 30]
print(adults)
ファイル処理での活用
# ファイルの行処理(例)
# lines = [" line 1 ", "", " line 2 ", " line 3 "]
# 空白行を除去し、前後の空白を削除
# cleaned_lines = [line.strip() for line in lines if line.strip()]
# print(cleaned_lines) # ['line 1', 'line 2', 'line 3']
# 特定の拡張子のファイルを抽出
filenames = ["doc.txt", "image.jpg", "data.csv", "script.py", "readme.md"]
python_files = [f for f in filenames if f.endswith(".py")]
print(python_files) # ['script.py']
text_files = [f for f in filenames if f.endswith((".txt", ".md"))]
print(text_files) # ['doc.txt', 'readme.md']
数学的処理での活用
# 素数の判定と抽出
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
primes = [n for n in range(2, 30) if is_prime(n)]
print(primes) # [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
# フィボナッチ数列の生成(一定範囲内)
def fibonacci_up_to(limit):
fib = [0, 1]
while fib[-1] + fib[-2] <= limit:
fib.append(fib[-1] + fib[-2])
return fib
fib_numbers = fibonacci_up_to(100)
even_fibs = [n for n in fib_numbers if n % 2 == 0]
print(even_fibs) # [0, 2, 8, 34]
内包表記使用時の注意点

読みやすさとのバランス
# 複雑すぎて読みにくい
complex_result = [
x * y for x in range(10)
for y in range(10)
if x % 2 == 0 and y % 3 == 0 and x * y > 10
]
# 読みやすく分割
def is_valid_pair(x, y):
return x % 2 == 0 and y % 3 == 0 and x * y > 10
readable_result = [
x * y for x in range(10) for y in range(10)
if is_valid_pair(x, y)
]
# または通常のfor文を使用
readable_result2 = []
for x in range(10):
for y in range(10):
if is_valid_pair(x, y):
readable_result2.append(x * y)
パフォーマンスの考慮
# 無駄な処理を含む
expensive_list = [expensive_function(x) for x in range(1000)]
# 条件で事前にフィルタリング
def expensive_function(x):
# 重い処理のシミュレーション
return x ** 3
efficient_list = [
expensive_function(x) for x in range(1000)
if x % 10 == 0 # 必要な要素のみ処理
]
副作用のある処理は避ける
# 副作用のある処理(推奨されない)
count = 0
def increment_and_return(x):
global count
count += 1
return x * 2
# このような使い方は避ける
# result = [increment_and_return(x) for x in range(10)]
# 純粋な関数を使用
def pure_function(x):
return x * 2
result = [pure_function(x) for x in range(10)]
よくある疑問
- Q内包表記と通常のfor文、どちらが速い?
- A
一般的に内包表記の方が高速です。ただし、複雑な処理では可読性を優先してfor文を使うことも重要です。
- Q何重までのネストが適切?
- A
2重まで(
for x in ... for y in ...
)が読みやすさの限界です。3重以上は通常のfor文を使いましょう。
- Q内包表記でエラーハンドリングはできる?
- A
直接はできません。エラーが発生する可能性がある場合は、事前に条件でフィルタリングするか、通常のfor文を使用してください。
# エラーが発生する可能性がある例 numbers = [1, 2, 0, 4, 5] # ゼロ除算エラーが発生 # result = [10 / x for x in numbers] # 事前にフィルタリング result = [10 / x for x in numbers if x != 0] print(result) # [10.0, 5.0, 2.5, 2.0]
- Q内包表記でbreakやcontinueは使える?
- A
使えません。このような制御が必要な場合は通常のfor文を使用してください。
まとめ
pythonの内包表記は、コードを簡潔で読みやすくする強力な機能です。
今回学んだポイント
- 基本構文:
[式 for 変数 in イテラブル]
- 条件付き:
if
でフィルタリング、三項演算子で変換 - 応用:辞書内包表記、集合内包表記、ネスト処理
- 実践活用:データ処理、ファイル操作、数学的計算
- 注意点:可読性とパフォーマンスのバランス
コメント