メインコンテンツへスキップ
Lesson5 / 6

辞書のループ処理

目次

1. このレッスンで学ぶこと

  • 辞書をループで処理する方法
  • keys(), values(), items()の使い方
  • ループ中の辞書変更
  • 実践的なループパターン

2. ループ処理とは

辞書のループ処理は、辞書の全要素を順番に処理する方法です。キーのみ、値のみ、またはキーと値の両方を同時に取得でき、データ処理やフィルタリングなど、様々な場面で活用できます。

ループ方法取得データ使用場面記法
キーでループキーのみキーベースの処理for key in dict:
values()でループ値のみ値の統計処理for value in dict.values():
items()でループキーと値両方が必要な場合for key, value in dict.items():
内包表記変換後のデータ辞書の生成・変換{k: v for k, v in dict.items()}

主な特徴:

  • for文で簡潔に全要素を処理可能
  • items()でキーと値を同時に取得(最も一般的)
  • ループ中の直接削除は禁止(リストを作ってから削除)
  • 辞書内包表記で効率的に新しい辞書を生成

簡単なコード例:

Python
scores = {"math": 85, "english": 92, "science": 78}

# キーと値でループ(最も一般的)
for subject, score in scores.items():
    print(f"{subject}: {score}点")

# 値でループ
total = sum(scores.values())
avg = total / len(scores)
print(f"平均: {avg:.1f}点")

# 辞書内包表記で変換
high_scores = {s: p for s, p in scores.items() if p >= 90}
print(high_scores)  # {'english': 92}

3. なぜループ処理が必要か?

辞書の全ての要素を処理したい場面は多くあります。

Python
scores = {"math": 85, "english": 92, "science": 78}

# 全ての科目の点数を表示したい
for subject, score in scores.items():
    print(f"{subject}: {score}点")

ループを使うことで、辞書の全要素を効率的に処理できます。

💡 豆知識: Python 3.7以降、辞書は挿入順序を保持します。そのため、ループで処理する際の順序は、要素を追加した順番と同じになります。これにより、辞書の動作がより予測可能になりました。


4. キーでループ

基本的なループ

機能: 辞書のキーを順番に取得してループします。

書き方:

Python
for キー in 辞書:
    # 処理

用途: キーベースの処理

注意点: デフォルトではキーのみ取得される

Python
user = {
    "name": "太郎",
    "age": 25,
    "city": "東京",
    "job": "エンジニア"
}

# キーでループ(最も基本)
print("=== キーのみ ===")
for key in user:
    print(f"キー: {key}")

# キーから値を取得
print("\n=== キーと値 ===")
for key in user:
    value = user[key]
    print(f"{key}: {value}")

# keys()を明示的に使う(同じ意味)
print("\n=== keys()使用 ===")
for key in user.keys():
    print(f"{key}: {user[key]}")

実行結果:

=== キーのみ ===
キー: name
キー: age
キー: city
キー: job

=== キーと値 ===
name: 太郎
age: 25
city: 東京
job: エンジニア

=== keys()使用 ===
name: 太郎
age: 25
city: 東京
job: エンジニア

キーの存在確認とループ

Python
inventory = {
    "apple": 10,
    "banana": 5,
    "orange": 0,
    "grape": 15
}

# 在庫があるものだけ処理
print("=== 在庫あり ===")
for item in inventory:
    if inventory[item] > 0:
        print(f"{item}: {inventory[item]}個")

# 在庫切れを確認
print("\n=== 在庫切れ ===")
for item in inventory:
    if inventory[item] == 0:
        print(f"{item}は在庫切れ")

# 在庫の合計
total = 0
for item in inventory:
    total += inventory[item]
print(f"\n総在庫数: {total}個")

実行結果:

=== 在庫あり ===
apple: 10個
banana: 5個
grape: 15個

=== 在庫切れ ===
orangeは在庫切れ

総在庫数: 30個

5. 値でループ

values()メソッド

機能: 辞書の値のみを順番に取得してループします。

書き方:

Python
forin 辞書.values():
    # 処理

用途: 値のみが必要な処理

注意点: キーは取得できない

Python
scores = {
    "math": 85,
    "english": 92,
    "science": 78,
    "history": 88,
    "art": 95
}

# 値でループ
print("=== 全ての点数 ===")
for score in scores.values():
    print(f"{score}点")

# 統計処理
total = sum(scores.values())
count = len(scores.values())
average = total / count

print(f"\n合計点: {total}")
print(f"科目数: {count}")
print(f"平均点: {average:.2f}")

# 最高点と最低点
max_score = max(scores.values())
min_score = min(scores.values())
print(f"最高点: {max_score}")
print(f"最低点: {min_score}")

# 条件に合う値をカウント
excellent_count = 0
for score in scores.values():
    if score >= 90:
        excellent_count += 1
print(f"\n90点以上: {excellent_count}科目")

実行結果:

=== 全ての点数 ===
85点
92点
78点
88点
95点

合計点: 438
科目数: 5
平均点: 87.60
最高点: 95
最低点: 78

90点以上: 2科目

6. キーと値でループ

items()メソッド

機能: 辞書のキーと値のペアを同時に取得してループします。

書き方:

Python
for キー,in 辞書.items():
    # 処理

用途: キーと値の両方が必要な処理

注意点: タプルのアンパックを使う

Python
products = {
    "ノートPC": 98000,
    "マウス": 1500,
    "キーボード": 3500,
    "モニター": 25000
}

# items()でループ(最も一般的)
print("=== 商品リスト ===")
for name, price in products.items():
    print(f"{name}: {price:,}円")

# 税込価格を計算
print("\n=== 税込価格 ===")
tax_rate = 0.1
for name, price in products.items():
    tax_included = int(price * (1 + tax_rate))
    print(f"{name}: {tax_included:,}円(税込)")

# 条件に合う商品を検索
print("\n=== 10,000円以上の商品 ===")
for name, price in products.items():
    if price >= 10000:
        print(f"{name}: {price:,}円")

# 最も高い商品
max_product = max(products.items(), key=lambda x: x[1])
print(f"\n最高額商品: {max_product[0]} ({max_product[1]:,}円)")

実行結果:

=== 商品リスト ===
ノートPC: 98,000円
マウス: 1,500円
キーボード: 3,500円
モニター: 25,000円

=== 税込価格 ===
ノートPC: 107,800円(税込)
マウス: 1,650円(税込)
キーボード: 3,850円(税込)
モニター: 27,500円(税込)

=== 10,000円以上の商品 ===
ノートPC: 98,000円
モニター: 25,000円

最高額商品: ノートPC (98,000円)

7. ネストした辞書のループ

2階層の辞書

Python
students = {
    "太郎": {
        "age": 20,
        "grade": "A",
        "score": 85
    },
    "花子": {
        "age": 19,
        "grade": "S",
        "score": 95
    },
    "次郎": {
        "age": 21,
        "grade": "B",
        "score": 78
    }
}

# ネストした辞書をループ
print("=== 学生情報 ===")
for name, info in students.items():
    print(f"\n{name}:")
    for key, value in info.items():
        print(f"  {key}: {value}")

# 特定の情報を抽出
print("\n=== 成績一覧 ===")
for name, info in students.items():
    grade = info["grade"]
    score = info["score"]
    print(f"{name}: {grade}評価 ({score}点)")

# 条件に合う学生を検索
print("\n=== 20歳以上の学生 ===")
for name, info in students.items():
    if info["age"] >= 20:
        print(f"{name}: {info['age']}歳")

実行結果:

=== 学生情報 ===

太郎:
  age: 20
  grade: A
  score: 85

花子:
  age: 19
  grade: S
  score: 95

次郎:
  age: 21
  grade: B
  score: 78

=== 成績一覧 ===
太郎: A評価 (85点)
花子: S評価 (95点)
次郎: B評価 (78点)

=== 20歳以上の学生 ===
太郎: 20歳
次郎: 21歳

8. ループ中の辞書変更

新しい辞書を作る方法

機能: ループ中に辞書を変更する安全な方法です。

書き方:

Python
新しい辞書 = {}
for キー,in 元の辞書.items():
    新しい辞書[新しいキー] = 新しい値

用途: 辞書の変換、フィルタリング

注意点: 元の辞書は変更しない

Python
prices = {
    "apple": 100,
    "banana": 80,
    "orange": 120,
    "grape": 200
}

# 値引き後の価格(新しい辞書)
discount_rate = 0.2
discounted = {}
for item, price in prices.items():
    discounted[item] = int(price * (1 - discount_rate))

print("=== 元の価格 ===")
for item, price in prices.items():
    print(f"{item}: {price}円")

print("\n=== 値引き後 ===")
for item, price in discounted.items():
    print(f"{item}: {price}円")

実行結果:

=== 元の価格 ===
apple: 100円
banana: 80円
orange: 120円
grape: 200円

=== 値引き後 ===
apple: 80円
banana: 64円
orange: 96円
grape: 160円

フィルタリング

Python
scores = {
    "太郎": 85,
    "花子": 92,
    "次郎": 65,
    "三郎": 88,
    "四郎": 55
}

# 合格者のみ抽出(80点以上)
passed = {}
for name, score in scores.items():
    if score >= 80:
        passed[name] = score

print("=== 合格者 ===")
for name, score in passed.items():
    print(f"{name}: {score}点")

# 不合格者
failed = {}
for name, score in scores.items():
    if score < 60:
        failed[name] = score

print("\n=== 不合格者 ===")
for name, score in failed.items():
    print(f"{name}: {score}点")

# 辞書内包表記で同じことができる
passed2 = {name: score for name, score in scores.items() if score >= 80}
print(f"\n内包表記: {passed2}")

実行結果:

=== 合格者 ===
太郎: 85点
花子: 92点
三郎: 88点

=== 不合格者 ===
四郎: 55点

内包表記: {'太郎': 85, '花子': 92, '三郎': 88}

ループ中の削除(注意が必要)

Python
# 危険な例(実行しないこと)
# data = {"a": 1, "b": 2, "c": 3}
# for key in data:
#     if data[key] > 1:
#         del data[key]  # RuntimeError!

# 安全な方法1: 削除するキーを集める
data = {"a": 1, "b": 2, "c": 3, "d": 4}
to_delete = []
for key, value in data.items():
    if value > 2:
        to_delete.append(key)

for key in to_delete:
    del data[key]

print(f"削除後: {data}")

# 安全な方法2: 新しい辞書を作る
data2 = {"a": 1, "b": 2, "c": 3, "d": 4}
data2 = {k: v for k, v in data2.items() if v <= 2}
print(f"フィルタ後: {data2}")

# 安全な方法3: リストに変換
data3 = {"a": 1, "b": 2, "c": 3, "d": 4}
for key in list(data3.keys()):
    if data3[key] > 2:
        del data3[key]
print(f"削除後: {data3}")

実行結果:

削除後: {'a': 1, 'b': 2}
フィルタ後: {'a': 1, 'b': 2}
削除後: {'a': 1, 'b': 2}

9. 辞書内包表記

基本的な内包表記

機能: ループを使って簡潔に辞書を作成します。

書き方:

Python
辞書 = {キー:for 変数 in イテラブル}

用途: 変換、フィルタリング、初期化

注意点: 読みやすさを保つ

Python
# 平方数の辞書
squares = {x: x**2 for x in range(1, 6)}
print(f"平方数: {squares}")

# 文字列から辞書
fruits = ["apple", "banana", "orange"]
fruit_lengths = {fruit: len(fruit) for fruit in fruits}
print(f"文字数: {fruit_lengths}")

# 既存の辞書を変換
prices = {"apple": 100, "banana": 80, "orange": 120}
tax_included = {item: int(price * 1.1) for item, price in prices.items()}
print(f"税込: {tax_included}")

# 条件付き
scores = {"太郎": 85, "花子": 92, "次郎": 65, "三郎": 88}
passed = {name: score for name, score in scores.items() if score >= 80}
print(f"合格者: {passed}")

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

実行結果:

平方数: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
文字数: {'apple': 5, 'banana': 6, 'orange': 6}
税込: {'apple': 110, 'banana': 88, 'orange': 132}
合格者: {'太郎': 85, '花子': 92, '三郎': 88}
入れ替え: {1: 'a', 2: 'b', 3: 'c'}

10. 具体例

例1: データの集計

Python
# 売上データ
sales = [
    {"product": "apple", "quantity": 10, "price": 100},
    {"product": "banana", "quantity": 5, "price": 80},
    {"product": "apple", "quantity": 8, "price": 100},
    {"product": "orange", "quantity": 12, "price": 120},
    {"product": "banana", "quantity": 3, "price": 80}
]

# 商品ごとの売上を集計
product_sales = {}
for sale in sales:
    product = sale["product"]
    amount = sale["quantity"] * sale["price"]

    if product in product_sales:
        product_sales[product] += amount
    else:
        product_sales[product] = amount

print("=== 商品別売上 ===")
for product, total in product_sales.items():
    print(f"{product}: {total:,}円")

# 総売上
grand_total = sum(product_sales.values())
print(f"\n総売上: {grand_total:,}円")

# 売上トップ3
sorted_sales = sorted(product_sales.items(), key=lambda x: x[1], reverse=True)
print("\n=== 売上トップ3 ===")
for i, (product, total) in enumerate(sorted_sales[:3], 1):
    print(f"{i}位: {product} ({total:,}円)")

実行結果:

=== 商品別売上 ===
apple: 1,800円
banana: 640円
orange: 1,440円

総売上: 3,880円

=== 売上トップ3 ===
1位: apple (1,800円)
2位: orange (1,440円)
3位: banana (640円)

例2: データの変換とマージ

Python
# 複数の辞書をマージ
user_basic = {"id": 1001, "name": "太郎"}
user_contact = {"email": "taro@example.com", "phone": "090-1234-5678"}
user_settings = {"theme": "dark", "language": "ja"}

# マージ
user_profile = {}
for d in [user_basic, user_contact, user_settings]:
    for key, value in d.items():
        user_profile[key] = value

print("=== プロフィール ===")
for key, value in user_profile.items():
    print(f"{key}: {value}")

# Python 3.9以降なら | 演算子も使える
# user_profile = user_basic | user_contact | user_settings

実行結果:

=== プロフィール ===
id: 1001
name: 太郎
email: taro@example.com
phone: 090-1234-5678
theme: dark
language: ja

例3: グループ化と統計

Python
# トランザクションデータ
transactions = [
    {"date": "2024-01-01", "category": "食費", "amount": 1200},
    {"date": "2024-01-01", "category": "交通費", "amount": 500},
    {"date": "2024-01-02", "category": "食費", "amount": 800},
    {"date": "2024-01-02", "category": "食費", "amount": 1500},
    {"date": "2024-01-03", "category": "交通費", "amount": 300}
]

# カテゴリ別に集計
by_category = {}
for trans in transactions:
    category = trans["category"]
    amount = trans["amount"]

    if category not in by_category:
        by_category[category] = {
            "count": 0,
            "total": 0,
            "transactions": []
        }

    by_category[category]["count"] += 1
    by_category[category]["total"] += amount
    by_category[category]["transactions"].append(trans)

# 結果表示
print("=== カテゴリ別集計 ===")
for category, data in by_category.items():
    count = data["count"]
    total = data["total"]
    average = total / count
    print(f"\n{category}:")
    print(f"  件数: {count}件")
    print(f"  合計: {total:,}円")
    print(f"  平均: {average:.0f}円")

# 総支出
grand_total = sum(data["total"] for data in by_category.values())
print(f"\n総支出: {grand_total:,}円")

実行結果:

=== カテゴリ別集計 ===

食費:
  件数: 3件
  合計: 3,500円
  平均: 1167円

交通費:
  件数: 2件
  合計: 800円
  平均: 400円

総支出: 4,300円

11. 練習問題

問題1(基礎)⭐☆☆

以下の辞書をループ処理して、全ての科目と点数を「科目: 点数点」の形式で表示してください。

Python
scores = {
    "数学": 85,
    "英語": 92,
    "理科": 78,
    "社会": 88
}
💡 ヒント
  • items()メソッドでキーと値を同時に取得
  • for文でループ処理
✅ 解答例
Python
scores = {
    "数学": 85,
    "英語": 92,
    "理科": 78,
    "社会": 88
}

print("=== 成績一覧 ===")
for subject, score in scores.items():
    print(f"{subject}: {score}点")

実行結果:

=== 成績一覧 ===
数学: 85点
英語: 92点
理科: 78点
社会: 88点

解説: items()メソッドを使うと、キーと値を同時に取得できます。これが辞書をループ処理する最も一般的な方法です。


問題2(基礎)⭐☆☆

以下の商品辞書から、values()を使って全ての価格の合計と平均を計算してください。

Python
products = {
    "りんご": 100,
    "バナナ": 80,
    "オレンジ": 120,
    "ぶどう": 200
}
💡 ヒント
  • values()で値のみを取得
  • sum()で合計を計算
  • len()で要素数を取得
✅ 解答例
Python
products = {
    "りんご": 100,
    "バナナ": 80,
    "オレンジ": 120,
    "ぶどう": 200
}

# 全ての価格を取得
prices = products.values()

# 合計と平均を計算
total = sum(prices)
count = len(prices)
average = total / count

print(f"合計: {total}円")
print(f"商品数: {count}個")
print(f"平均価格: {average:.1f}円")

実行結果:

合計: 500円
商品数: 4個
平均価格: 125.0円

解説: values()メソッドで全ての値を取得し、sum()len()を使って統計処理を行います。


問題3(応用)⭐⭐☆

以下の学生辞書から、80点以上の学生だけを抽出した新しい辞書を作成してください。辞書内包表記を使って実装してください。

Python
students = {
    "太郎": 85,
    "花子": 92,
    "次郎": 65,
    "三郎": 88,
    "四郎": 55,
    "五郎": 78
}
💡 ヒント
  • 辞書内包表記: {key: value for key, value in dict.items() if 条件}
  • 条件はvalue >= 80
✅ 解答例
Python
students = {
    "太郎": 85,
    "花子": 92,
    "次郎": 65,
    "三郎": 88,
    "四郎": 55,
    "五郎": 78
}

# 辞書内包表記で80点以上を抽出
passed = {name: score for name, score in students.items() if score >= 80}

print("=== 全学生 ===")
for name, score in students.items():
    print(f"{name}: {score}点")

print("\n=== 80点以上(合格者)===")
for name, score in passed.items():
    print(f"{name}: {score}点")

print(f"\n合格者数: {len(passed)}人 / {len(students)}人")

実行結果:

=== 全学生 ===
太郎: 85点
花子: 92点
次郎: 65点
三郎: 88点
四郎: 55点
五郎: 78点

=== 80点以上(合格者)===
太郎: 85点
花子: 92点
三郎: 88点

合格者数: 3人 / 6人

解説: 辞書内包表記を使うと、条件に合う要素だけを抽出した新しい辞書を簡潔に作成できます。if条件で80点以上の学生だけをフィルタリングしています。


12. まとめ

このレッスンでは、辞書をループで処理する方法を学びました。

  • for key in dictitems() の使い分けを理解しました。
  • キー・値の同時処理で実践的な集計や表示を実装できました。
  • ネストしたデータでも段階的に取り出す手順を確認しました。
  • ループ内で条件分岐を組み合わせた辞書処理を練習しました。
  • 辞書構造を把握してから反復することがバグ防止につながります。