Pythonの辞書(dict)はキーと値のペアを扱う柔軟なデータ構造です。
本記事では、初心者の方でも確実に使いこなせるように、追加・取得・削除という3つの基本操作を段階的に説明します。
実行可能なサンプルコードと出力つきで、エラー時の対処や書き分けのコツも丁寧に解説します。
辞書(dict)の基本と作成
辞書とは(キーと値のペア)
辞書はキー(key)と値(value)のペアを対応付けるデータ構造です。
キーは重複できず、検索や更新が高速です。
Pythonの辞書はPython 3.7以降で挿入順を保持します。
キーにはハッシュ可能(不変)な型(例:int、str、tupleなど)を使います。
値はどのような型でも構いません。
辞書リテラルは{}
、型名はdict
です。
空の辞書を作る({} / dict())
空の辞書はリテラルかコンストラクタのどちらでも作成できます。
どちらを使っても意味は同じです。
# 空の辞書の作成方法は2通りあります
a = {}
b = dict()
print(type(a), a) # {} を使う
print(type(b), b) # dict() を使う
<class 'dict'> {}
<class 'dict'> {}
初期値つきの辞書を作る
典型的にはリテラル、キーワード引数、シーケンスからの生成などを使います。
用途に応じて最も読みやすい方法を選びます。
# 1) リテラルで一度に定義
user = {"name": "Alice", "age": 20}
# 2) キーワード引数 (キーが識別子として有効な場合)
config = dict(debug=True, retry=3)
# 3) (キー, 値)のペア列から生成
pairs = [("x", 1), ("y", 2)]
point = dict(pairs)
# 4) fromkeysでキー集合から同一値を割り当て
# 注意: ミュータブルな値を使うと全キーで共有されるので注意
keys = ["a", "b", "c"]
same_zero = dict.fromkeys(keys, 0)
print(user)
print(config)
print(point)
print(same_zero)
{'name': 'Alice', 'age': 20}
{'debug': True, 'retry': 3}
{'x': 1, 'y': 2}
{'a': 0, 'b': 0, 'c': 0}
dict.fromkeys(keys, [])
のようにリストを使うと、すべてのキーが同じリストを共有します。
別々のリストが必要な場合は内包表記などで個別に用意します。
Pythonの辞書への要素追加
代入でキーを追加する
最もシンプルな方法は代入です。
存在しないキーなら追加、存在するキーなら上書きになります。
inventory = {"apple": 3}
# 新しいキーの追加
inventory["banana"] = 5
# 既存キーの上書き
inventory["apple"] = 10
print(inventory)
{'apple': 10, 'banana': 5}
setdefault(key, default)で存在しない時だけ追加
setdefault
はキーが無いときだけ追加し、あれば何もしません。
戻り値は辞書に保存された値です。
初期化を伴うカウンタやグルーピングに便利です。
counts = {}
# 'red' が無ければ 0 を入れて、その値を返す
r = counts.setdefault("red", 0)
# 既にある場合は変更しない
counts["red"] = counts["red"] + 1
s = counts.setdefault("red", 999) # ここでは追加も上書きもしない
print(counts, r, s)
{'red': 1} 0 1
update({…})で複数まとめて追加
update
は複数のキーを一度に追加・上書きします。
辞書、イテラブルのペア、キーワード引数などを受け取れます。
profile = {"name": "Alice"}
# 辞書でまとめて更新
profile.update({"age": 21, "country": "JP"})
# (キー, 値)のシーケンスでもOK
profile.update([("age", 22), ("city", "Tokyo")])
# キーワード引数でもOK (キーが識別子として有効な場合)
profile.update(active=True)
print(profile)
{'name': 'Alice', 'age': 22, 'country': 'JP', 'city': 'Tokyo', 'active': True}
マージ演算子(|, |=)で追加/上書き
Python 3.9以降ではマージ演算子を使えます。
a | b
は新しい辞書を返し、a |= b
は破壊的に更新します。
base = {"a": 1, "common": 0}
extra = {"b": 2, "common": 99}
# 新しい辞書を作る (base はそのまま)
merged = base | extra
# 破壊的に更新 (base 自体が書き換わる)
base |= extra
print("merged:", merged)
print("base:", base)
print("extra:", extra)
merged: {'a': 1, 'common': 99, 'b': 2}
base: {'a': 1, 'common': 99, 'b': 2}
extra: {'b': 2, 'common': 99}
ポイント: 右側の辞書の値が優先されます。
3.9未満ではupdate
を使います。
Pythonの辞書から要素を取得
d[key]で値を取り出す
もっとも直接的な参照方法です。
KeyError
が発生する可能性があるため、存在が確実なキー向けです。
conf = {"timeout": 10}
print(conf["timeout"]) # 存在するので取得できる
# 存在しないキーは KeyError になる
try:
print(conf["retries"])
except KeyError as e:
print("KeyError:", e)
10
KeyError: 'retries'
get(key, default)で安全に取得
get
は存在しない場合にデフォルト値を返すので安全です。
辞書を変更しません。
conf = {"timeout": 10}
print(conf.get("timeout")) # 見つかればその値
print(conf.get("retries")) # 無ければ None
print(conf.get("retries", 3)) # 無ければ 3 を返す(辞書は変化しない)
print(conf) # そのまま
10
None
3
{'timeout': 10}
違いの要点: get
は辞書を変えませんが、setdefault
は無いと追加します。
inでキーの有無を確認
in
演算子はキーの存在チェックに使います。
値の存在ではない点に注意してください。
d = {"x": 1, "y": 2}
print("x" in d) # キー 'x' はある
print(2 in d) # 値 2 は対象外 (False)
print("z" not in d) # 無いので True
True
False
True
keys/values/itemsで一覧を取得
ビューオブジェクトを返します。
イテラブルであり、必要に応じてlist
でリスト化できます。
d = {"x": 1, "y": 2, "z": 3}
print(list(d.keys())) # キー一覧
print(list(d.values())) # 値一覧
print(list(d.items())) # (キー, 値)のタプル一覧
# 反復で使う例
for k, v in d.items():
print(f"{k} => {v}")
['x', 'y', 'z']
[1, 2, 3]
[('x', 1), ('y', 2), ('z', 3)]
x => x
y => 2
z => 3
上の反復結果は実行順に依存します。
辞書は挿入順を保持しますが、ソートは行いません。
順序が必要ならsorted(d.items())
を使います。
Pythonの辞書の要素を削除
del d[key]で削除する
キーが存在する前提ならdel
が最速です。
無ければKeyError
になります。
d = {"a": 1, "b": 2}
del d["a"] # 'a' を削除
print(d)
# 無いキーを削除すると KeyError
try:
del d["c"]
except KeyError as e:
print("KeyError:", e)
{'b': 2}
KeyError: 'c'
pop(key[, default])で取り出して削除
pop
は値を返しつつ削除します。
デフォルト値を渡せば、無いときでも例外を出さずにその値を返します。
d = {"a": 1, "b": 2}
val = d.pop("a") # 取り出して削除
print(val, d)
missing = d.pop("c", 0) # 無ければ 0 を返す(例外なし)
print(missing, d)
1 {'b': 2}
0 {'b': 2}
popitem()で最後の要素を削除
popitem()
はLIFO(最後に入れた要素)を(キー, 値)のタプルで返して削除します。
空ならKeyError
です。
d = {}
d["x"] = 1
d["y"] = 2
item = d.popitem()
print("popped:", item)
print("after:", d)
# 空で呼ぶと KeyError
try:
empty = {}.popitem()
except KeyError as e:
print("KeyError:", e)
popped: ('y', 2)
after: {'x': 1}
KeyError: 'popitem(): dictionary is empty'
clear()で全て削除
全要素を削除して空辞書にします。
d = {"a": 1, "b": 2}
d.clear()
print(d)
{}
存在しないキーの削除時の対処
削除時の安全策はいくつかあります。
状況に応じて選びます。
d = {"a": 1}
# 1) 事前に存在確認して del
if "b" in d:
del d["b"] # 実行されない
else:
print("'b' は無いのでスキップ")
# 2) pop にデフォルトを渡す (例外を出さない)
removed = d.pop("b", None)
print("removed:", removed, "dict:", d)
# 3) 例外処理で囲む (存在しないことが稀ならこれが最も速いことも)
try:
del d["b"]
except KeyError:
pass # ログなどの処理に置き換え可能
print(d)
'b' は無いのでスキップ
removed: None dict: {'a': 1}
{'a': 1}
実装の指針: 制御フローが単純ならpop(key, default)
、同時に値が欲しいならpop
、明示的な存在確認が読みやすいならin
を使います。
早見表: 辞書操作の使い分け
操作の選択基準を一覧にまとめます。
例外の有無と辞書が変化するかが判断の軸です。
用途 | 構文 | 存在しないキー | 返り値 | 辞書の変更 |
---|---|---|---|---|
追加(単独) | d[k] = v | 追加される | なし | 変わる |
追加(条件付き) | d.setdefault(k, v) | 追加する | 設定された値 | 変わる |
追加(複数) | d.update({...}) | 追加/上書き | なし | 変わる |
追加(3.9+) | d | e / d |= e | 追加/上書き | 新辞書/なし | 新規/変わる |
取得(厳密) | d[k] | KeyError | 値 | 変わらない |
取得(安全) | d.get(k, default) | default | 値/default | 変わらない |
存在確認 | k in d | False | True/False | 変わらない |
削除 | del d[k] | KeyError | なし | 変わる |
削除+取得 | d.pop(k[, default]) | default/KeyError | 値/default | 変わる |
末尾削除 | d.popitem() | KeyError(空) | (k, v) | 変わる |
全削除 | d.clear() | – | なし | 変わる |
まとめ
辞書はキーで高速にアクセスできる柔軟なマップです。
追加はd[k] = v
やupdate
、3.9以降なら|
演算子が便利です。
取得はd[k]
で厳密に、存在が不確実ならget
やin
で安全に扱います。
削除はdel
やpop
を使い分け、存在しない可能性があるならpop(key, default)
やtry/except
で対処します。
これらの基礎を押さえれば、実務でも設定管理や集計、データ変換などで確実に使いこなせます。