Python | データ構造:dict

Python
スポンサーリンク

辞書の概要(名前で値を取り出す「キーと値のペア」)

dict(辞書)は「キー」と「値」をペアで管理するデータ構造です。リストが“番号(インデックス)”で取り出すのに対して、辞書は“名前(キー)”で直に参照できます。ユーザー情報、設定、集計結果、JSONの扱いなど「項目名が意味を持つ」データに向いています。

user = {"name": "Hanako", "age": 20, "city": "Tokyo"}
print(user["name"])  # "Hanako"
Python

基本の作り方と取り出し(ここが重要)

キーと値のペアで初期化する

空は {} または dict()。キーには文字列・数値・タプルなど“ハッシュ可能”な型を使います(リストや辞書は不可)。

empty = {}
user  = {"name": "Taro", "age": 25}
config = dict(theme="dark", lang="ja")  # キーワード引数でも作れる
Python

値の参照と KeyError の回避

存在しないキーを [] で参照すると KeyError。get を使うと「見つからない場合の既定値」を返せます。

print(user["name"])               # 参照
# print(user["email"])            # KeyError

print(user.get("email"))          # None(既定)
print(user.get("email", "N/A"))   # "N/A"(既定値を指定)
Python

追加・更新・削除

代入で追加・更新、del で削除、pop は削除しつつ値を返します。

user["email"] = "taro@example.com"  # 追加/更新
del user["age"]                     # 削除
email = user.pop("email", None)     # 値を返しつつ削除(なければ None)
Python

走査と便利メソッド(items・keys・values・update)

items・keys・values で効率よく回す

キーと値を同時に扱うなら items が定番です。keys はキー一覧、values は値一覧を返します。

for key, value in user.items():
    print(key, value)

print(list(user.keys()))   # ["name", "city"]
print(list(user.values())) # ["Taro", "Tokyo"]
Python

update でまとめて反映、| で辞書のマージ

update は別の辞書やペア列で一括更新します。Python 3.9+ では | で新しい辞書としてマージできます。

user.update({"city": "Osaka", "age": 26})  # まとめて更新
merged = {"a": 1} | {"b": 2, "a": 99}      # 新辞書(右優先)
print(merged)  # {"a": 99, "b": 2}
Python

setdefault で「なければ初期値を入れて返す」

集合やリストを「キーごとの箱」として育てるときに便利です。

groups = {}
groups.setdefault("admins", []).append("hanako")
groups.setdefault("admins", []).append("taro")
print(groups)  # {"admins": ["hanako", "taro"]}
Python

深掘りポイント(順序・ハッシュ可能・コピーの性質)

追加順が保持される(Python 3.7+)

辞書は「挿入順」を保持します。並びが意味を持つ UI 表示などでも使いやすくなりました。

d = {}
d["first"] = 1
d["second"] = 2
d["third"] = 3
print(list(d.keys()))  # ["first", "second", "third"]
Python

キーはハッシュ可能な不変型を使う

数値・文字列・タプルはキーにでき、リストや辞書は不可。

ok   = {(1, 2): "point"}   # タプルならキーにできる
# bad = {[1, 2]: "point"}  # TypeError(不可)
Python

浅いコピーと深いコピー

copy は浅いコピーで、入れ子のミュータブルは共有されます。完全に独立させたいなら deepcopy。

import copy
d = {"cfg": {"theme": "dark"}}
shallow = d.copy()
deep    = copy.deepcopy(d)
shallow["cfg"]["theme"] = "light"
print(d["cfg"]["theme"])   # "light"(共有されてる)
print(deep["cfg"]["theme"])# "dark"(独立)
Python

実用パターン(JSON・集計・ネスト・バリデーション)

JSONの読み書きと辞書の相性

Python の json モジュールは辞書と相互変換しやすいです。

import json
user = {"name": "Hanako", "age": 20}
text = json.dumps(user, ensure_ascii=False)  # 辞書→文字列
back = json.loads(text)                       # 文字列→辞書
Python

集計・グルーピング

キーを「カテゴリ」にして集計するのが直感的です。

sales = [("coffee", 2), ("tea", 1), ("coffee", 3)]
total = {}
for item, qty in sales:
    total[item] = total.get(item, 0) + qty
print(total)  # {"coffee": 5, "tea": 1}
Python

ネスト辞書で構造化

階層を辞書で表し、items で段階的に走査します。

store = {
    "coffee": {"price": 350, "qty": 2},
    "tea":    {"price": 280, "qty": 1},
}
for name, info in store.items():
    print(name, info["price"] * info["qty"])
Python

バリデーションと既定値反映

get と in を組み合わせて安全に取り出し、足りない項目は既定値で補います。

def normalize_user(d: dict) -> dict:
    return {
        "name": d.get("name", "unknown"),
        "age":  d.get("age", 0),
        "email": d.get("email"),
    }
Python

例題で身につける(定番から一歩先まで)

例題1:辞書から安全に取り出す

user = {"name": "Taro"}
print(user.get("age", "N/A"))  # "N/A"
Python

例題2:更新・削除・存在確認

user = {"name": "Taro", "age": 25}
user["age"] = 26
if "email" not in user:
    user["email"] = "taro@example.com"
removed = user.pop("age", None)
print(removed, user)  # 26 {'name': 'Taro', 'email': 'taro@example.com'}
Python

例題3:キー・値・ペアの列挙

product = {"name": "coffee", "price": 350, "qty": 2}
print(list(product.keys()))    # ['name', 'price', 'qty']
print(list(product.values()))  # ['coffee', 350, 2]
for k, v in product.items():
    print(k, v)
Python

例題4:辞書のマージと上書きルール

base = {"host": "localhost", "port": 8000}
override = {"port": 8080, "debug": True}
conf = base | override  # 3.9+
print(conf)  # {'host': 'localhost', 'port': 8080, 'debug': True}
Python

落とし穴とベストプラクティス(初心者がつまずきやすい点)

KeyError を避ける基本

存在しないキーを [] で参照すると KeyError。get を使う、in で存在確認、pop の既定値を使うのが安全。

キーの型混在で意図せぬバグ

“1” と 1 は別キー。キーの型を仕様で統一し、入力時点で正規化する。

変更しながら走査は慎重に

ループ中に辞書を直接更新・削除すると混乱しやすい。新辞書に書き出す、list(d.items()) で固定スナップショットを回す

d = {"a": 1, "b": 2, "c": 3}
for k, v in list(d.items()):
    if v % 2 == 1:
        del d[k]
print(d)  # {'b': 2}
Python

まとめ

dict は「キーで値を即参照できる」柔軟な基礎構造で、設定、集計、JSON、ネスト構造に強いです。get・pop・items・update・setdefault を使いこなし、KeyError 回避、キーの型統一、ハッシュ可能なキー、浅い/深いコピーの違いを押さえること。挿入順が保持される性質も活用しながら、安全な走査と更新パターンを身につければ、初心者でも読みやすく堅牢な辞書処理を書けます。

タイトルとURLをコピーしました