閉じる

Pythonの辞書(dict)とは?キーと値で管理する基本と使い方

辞書(dict)は、データをキーと値のペアで関連付けて管理するためのデータ構造です。

リストが位置(インデックス)でアクセスするのに対し、辞書はキーで直接探せるため、設定値、検索テーブル、名称と値の対応関係などに向いています。

「名前→点数」「商品コード→在庫数」「設定名→値」といった用途で威力を発揮します。

辞書(dict)とは?キーと値で管理する基本

Pythonの辞書の役割とリストとの違い

辞書は、キーから値を瞬時に取り出すための構造です。

リストは順序とインデックス重視ですが、辞書は意味のあるキーで管理するため、意図が明確になりやすいです。

例えば名前から点数を知りたいとき、リストでは全体を探す必要がありますが、辞書ならキーで直接アクセスできます。

以下はリストと辞書の典型的な違いです。

  • リストはscores[0]のように位置でアクセスします。要素の順序が意味を持ちます。
  • 辞書はscores["Alice"]のようにキーでアクセスします。順序ではなく対応関係が意味を持ちます。

簡単な例を示します。

Python
# 名前をキー、点数を値として管理する辞書
scores = {"Alice": 92, "Bob": 78, "Charlie": 85}

# キーで直接アクセスできる(高速で簡潔)
print(scores["Alice"])   # 92
実行結果
92

使いどころ(検索・設定・マッピング)

辞書は次のような場面で効果的です。

コード全体の可読性も高まります。

  • 検索テーブル(文字から数字、拡張子からMIMEタイプなど)
  • 設定値の保存(設定名→値)
  • ラベルや名前のマッピング(ユーザーID→プロフィール)

「キーの集合」から「値の集合」へ対応付けると考えると理解しやすいです。

辞書の作り方({} と dict())

辞書はリテラルの{}またはコンストラクタのdict()で作れます。

Python
# 1) リテラルで作成
person = {"name": "Alice", "age": 30}

# 2) 空の辞書を作って後から追加
empty = {}

# 3) dict() でキーワード引数から作成(キーは文字列に限る)
config = dict(debug=True, retries=3)

# 4) (キー, 値)のペア列から作成
pairs = [("host", "localhost"), ("port", 5432)]
db = dict(pairs)

# 5) 辞書内包表記で変換しながら作成
squares = {n: n*n for n in range(3)}  # {0:0, 1:1, 2:4}

print(person)
print(config)
print(db)
print(squares)
実行結果
{'name': 'Alice', 'age': 30}
{'debug': True, 'retries': 3}
{'host': 'localhost', 'port': 5432}
{0: 0, 1: 1, 2: 4}

辞書の基本操作(追加・取得・更新・削除)

要素を追加/更新する(dict[key] と update)

辞書名[キー] = 値で追加または更新できます。

すでに存在するキーに代入すると上書きになります。

まとめて変更したい場合はupdate()が便利です。

Python
settings = {"theme": "light", "lang": "ja"}

# 追加
settings["timeout"] = 10   # 新しいキーを追加

# 更新(同じキーに代入すると上書き)
settings["theme"] = "dark"

# まとめて更新(update)。既存キーは上書き、新規キーは追加
settings.update({"lang": "en", "autosave": True})

print(settings)
実行結果
{'theme': 'dark', 'lang': 'en', 'timeout': 10, 'autosave': True}

値を取得する([] と get の違い)

[]アクセスはキーがないとKeyErrorになります。

安全に取り出したいときはget()を使い、見つからない場合のデフォルト値を与えます。

Python
user = {"name": "Bob", "age": 20}

# [] は必須のキーに向く。存在しないと KeyError
print(user["name"])  # 正常
# print(user["email"])  # KeyError: 'email' (コメント解除でエラー)

# get は見つからないと None(または指定デフォルト)を返す
print(user.get("email"))            # None
print(user.get("email", "N/A"))     # "N/A" を返す
実行結果
Bob
None
N/A

[]は必須のキー、getは任意のキーという使い分けが基本です。

要素を削除する(del・pop・clear)

単一のキー削除はdel d[key]またはpop(key)を使います。

popは削除した値を返すので、同時に取得したいときに便利です。

全削除はclear()です。

Python
stock = {"A": 10, "B": 5, "C": 0}

# 値を取り出しつつ削除
b = stock.pop("B")     # b は 5
print("popped:", b)
print(stock)

# del は値を返さない
del stock["C"]
print(stock)

# 安全に pop したい場合はデフォルト値を渡す
x = stock.pop("X", 0)  # X が無ければ 0 を返す
print("popped X:", x)

# 全削除
stock.clear()
print(stock)
実行結果
popped: 5
{'A': 10, 'C': 0}
{'A': 10}
popped X: 0
{}

キーの存在確認(in と get)

キーの存在を確認するにはinが明確です。

getは値が0や空文字""のときも「偽」と判定されるため、存在確認にはinを推奨します。

Python
data = {"count": 0, "name": ""}

print("count" in data)           # True
print("missing" in data)         # False

# get は存在しないと None を返す。値が0や""のときの判定に注意
print(data.get("count") is not None)   # True (存在する)
print(bool(data.get("name")))          # False (空文字は偽だがキーは存在)
実行結果
True
False
True
False

初期化パターン(空・初期値付き)

空で作って後から埋めるほか、全キーを同じ値で始めたいときはdict.fromkeys()が使えます。

また、辞書内包表記で柔軟に初期化できます。

Python
# 空で開始
d1 = {}

# fromkeys で同一初期値(注意: ミュータブル値は共有される)
fields = ["host", "port", "user"]
d2 = dict.fromkeys(fields, None)  # 全て None で初期化

# 辞書内包表記で個別の初期値を計算
defaults = {k: (0 if k == "port" else "") for k in fields}

print(d1)
print(d2)
print(defaults)
実行結果
{}
{'host': None, 'port': None, 'user': None}
{'host': '', 'port': 0, 'user': ''}

走査と便利メソッドの使い方

ループで回す(for・items)

辞書をループする基本は2通りです。

キーだけ回すか、items()でキーと値を同時に受け取ります。

Python
prices = {"apple": 120, "banana": 90, "orange": 150}

# キーだけループ
for name in prices:
    print(name, prices[name])  # 値は辞書参照で取得

print("---")

# キーと値を同時にループ
for name, price in prices.items():
    print(name, price)
実行結果
apple 120
banana 90
orange 150
---
apple 120
banana 90
orange 150

keys()/values()/items()の使い分け

  • keys()はキーのビュー、values()は値のビュー、items()は(キー, 値)のビューを返します。ビューは動的で、辞書の変更を反映します。
  • 値だけ集めて合計するなどはvalues()、キーと値を一緒に処理するならitems()が読みやすいです。
Python
scores = {"A": 10, "B": 20, "C": 30}

total = sum(scores.values())
pairs = list(scores.items())  # リスト化して並べ替えやスライスに使える

print(total)
print(pairs)
実行結果
60
[('A', 10), ('B', 20), ('C', 30)]

デフォルト値で安全に取り出す(get・setdefault)

get()は読み取り専用、setdefault()は「無ければ入れて返す」という挙動です。

カウントやグルーピングの初期化に役立ちます。

Python
text = "banana"
counter = {}

# setdefault を使って初期化しながらカウント
for ch in text:
    counter.setdefault(ch, 0)  # 無ければ 0 をセット
    counter[ch] += 1

print(counter)  # {'b': 1, 'a': 3, 'n': 2}

# get なら読み取り専用でデフォルトを返す
x = counter.get("x", 0)
print("count(x) =", x)
実行結果
{'b': 1, 'a': 3, 'n': 2}
count(x) = 0

辞書を結合する(update・|)

辞書をマージするには破壊的なupdate()と、新しい辞書を返す|(パイプ演算子、Python 3.9+)があります。

重複キーは右側が優先されます。

Python
base = {"host": "localhost", "port": 8000}
override = {"port": 8080, "debug": True}

# 1) 破壊的に結合
merged1 = base.copy()
merged1.update(override)

# 2) 新しい辞書を返す(元は変えない)
merged2 = base | override

print("base:", base)
print("merged1:", merged1)
print("merged2:", merged2)
実行結果
base: {'host': 'localhost', 'port': 8000}
merged1: {'host': 'localhost', 'port': 8080, 'debug': True}
merged2: {'host': 'localhost', 'port': 8080, 'debug': True}

updateは左辺を変更、|は新しい辞書という違いを覚えると安全です。

注意点とベストプラクティス

キーに使える型(ハッシュ可能)

辞書のキーはハッシュ可能(immutable)である必要があります。

例えば文字列、整数、タプルは使えますが、リストや辞書は使えません。

タプルは中身もハッシュ可能でなければなりません。

Python
ok = {("x", 1): "point"}   # タプルはキーにできる

try:
    bad = {["x", 1]: "point"}  # リストはキーにできない
except TypeError as e:
    print(type(e).__name__, str(e))
実行結果
TypeError unhashable type: 'list'

重複キーは上書きされる

同じキーを複数回指定すると、最後の値で上書きされます。

リテラル中の重複も最後が有効です。

Python
d = {"a": 1, "a": 2}
print(d)  # 最後の 2 が残る
実行結果
{'a': 2}

挿入順序の保持と並び替え(sorted)

Python 3.7以降、辞書は挿入順序を保持します。

ただし、ある並べ替え基準で見たい場合はsorted()items()を使って並べ替えたリストを扱います。

Python
scores = {"Bob": 78, "Alice": 92, "Charlie": 85}

# 追加した順序を保持
for name in scores:
    print(name, scores[name])

print("--- sort by score desc ---")

# 値で降順ソートして表示
for name, score in sorted(scores.items(), key=lambda kv: kv[1], reverse=True):
    print(name, score)
実行結果
Bob 78
Alice 92
Charlie 85
--- sort by score desc ---
Alice 92
Charlie 85
Bob 78

よくあるエラー(KeyError)の回避

KeyErrorは存在しないキーを[]で参照したときに発生します。

回避には次の方針が有効です。

  • 任意キーの取得はget(key, default)を使う
  • 事前にif key in d:で確認する
  • 追加しながら使う場合はsetdefault()で初期化する
Python
config = {"retries": 3}

# 安全な読み取り
timeout = config.get("timeout", 5)  # 無ければ 5
print(timeout)

# 必須なら確認してから使う
if "retries" in config:
    print("retries:", config["retries"])
実行結果
5
retries: 3

参考までに、ネストした辞書では段階的にget()を使うと安全です。

例えばcfg.get("db", {}).get("host", "localhost")のようにデフォルトの空辞書を渡します。

まとめ

辞書(dict)はキーと値のペアで素早く検索・更新できる強力なデータ構造です。

作成は{}またはdict()で簡単に行え、追加や更新はd[key] = value、安全な取得はget()、削除はpop()delを使います。

走査はitems()でキーと値を同時に扱うと明快です。

結合はupdate()|を状況に応じて選びます。

キーはハッシュ可能な型に限定され、重複キーは上書きされる点に注意してください。

必須なら[]、任意ならgetという基本と、inで存在確認を押さえれば、エラーを避けつつ読みやすいコードを書けます。

まずは小さな設定や検索テーブルから、辞書の扱いに慣れていきましょう。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!