Python | データ構造:dict.get

Python
スポンサーリンク

dict.get の概要(安全に値を取り出す“優しい参照”)

dict.get は、辞書からキーに対応する値を「エラーなく」取り出すためのメソッドです。存在しないキーを指定すると、例外(KeyError)ではなく None(または指定した既定値)を返します。ユーザー入力や外部データの処理など“不足があり得る”場面で、コードをシンプルかつ安全にします。

user = {"name": "Hanako", "age": 20}
print(user.get("name"))          # "Hanako"
print(user.get("email"))         # None(存在しないため)
print(user.get("email", "N/A"))  # "N/A"(既定値を返す)
Python

基本の使い方と挙動(ここが重要)

既定値の指定と戻り値

get(key, default=None) の形で使います。キーがあれば値、なければ default を返します。default を省略すると None が返ります。get は「辞書を変更しない」点が重要です(見つからなくてもキーの追加はしません)。

conf = {"theme": "dark"}
print(conf.get("theme", "light"))  # "dark"
print(conf.get("lang",  "ja"))     # "ja"(キーがないため既定値)
Python

[] 参照との違い(KeyError を避ける)

辞書の [] は「必ず存在する前提」の直接参照で、見つからないと KeyError になります。get は「不足していても安全に進めたい」場面で使い、必須項目なら [] で早めにエラーに気づく設計が良いです。

data = {"price": 350}
# 必須なら:
p = data["price"]    # ないと KeyError
# 任意なら:
c = data.get("color", "black")  # 安全に既定値へ
Python

“falsy”な値と誤判定に注意

値が 0 や “”(空文字)でも「キーは存在」しています。よくある誤りは、get(… ) or 既定値 と書いてしまうこと。この書き方だと 0 や “” を“欠損”と誤判定して既定値に置き換えてしまいます。存在チェックは in を使うのが確実です。

d = {"count": 0}
# 誤りやすい:
print(d.get("count") or 999)  # 999(0がfalsyなため誤置換)

# 正しくは:
val = d.get("count")
if "count" in d:
    print(val)                # 0
else:
    print(999)
Python

setdefault との使い分け(辞書を“育てる”かどうか)

get は“読み取り”、setdefault は“足りなければ作る”

get は辞書を変えません。一方、setdefault(key, default) は「キーがなければ default を入れてから、その値を返す」ため、辞書を育てたいときに便利です。箱(リストや集合)をキーごとに初期化する定番です。

groups = {}
name = "hanako"

# get:読み取りのみ(作らない)
print(groups.get("admins", []))       # []

# setdefault:なければ作って返す(辞書が変わる)
groups.setdefault("admins", []).append(name)
print(groups)  # {"admins": ["hanako"]}
Python

既存データを汚したくない場面では get、キーごとの構造を育てたい場面では setdefault を選びます。


実用パターン(入力の正規化・安全な取り出し・集計)

任意フィールドの正規化(欠損は既定値で補う)

def normalize_user(d: dict) -> dict:
    return {
        "name":  d.get("name",  "unknown"),
        "age":   d.get("age",   0),
        "email": d.get("email")  # 任意:None も許容
    }

print(normalize_user({"name": "Taro"}))
# {'name': 'Taro', 'age': 0, 'email': None}
Python

ネストした辞書の安全な参照

1段目が欠損する可能性を考え、空辞書を既定値にしてから次を参照します。短いのに安全。

store = {"coffee": {"price": 350, "qty": 2}}
info  = store.get("coffee", {})
print(info.get("price", 0))  # 350
print(store.get("tea", {}).get("price", 0))  # 0(欠損でも安全)
Python

既定値付き集計(カウンタの基本形)

get を使えば、存在しないキーを 0 とみなして加算できます。

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

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

例題1:エラーなし取り出しと既定値

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

例題2:JSON風データの安全な参照

payload = {"meta": {"version": 3}}
version = payload.get("meta", {}).get("version", 1)
print(version)  # 3
Python

例題3:falsyを既定値と誤解しない取り扱い

conf = {"timeout": 0}
timeout = conf.get("timeout") if "timeout" in conf else 30
print(timeout)  # 0
Python

例題4:setdefault との対比(育てる辞書)

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

落とし穴とベストプラクティス(重要ポイントを深掘り)

default の評価タイミング

get に渡す default の式は、呼び出し前に評価されます(“遅延”ではありません)。コストの重い処理を default に書くと、キーが存在していても毎回実行されます。回避するには軽い値を渡す、または in で存在を確認してから重い処理を呼びましょう。

# 悪い例(毎回 heavy() が実行される)
value = d.get("key", heavy())

# 良い例
if "key" in d:
    value = d["key"]
else:
    value = heavy()
Python

値の型混在と既定値の型不一致

get の既定値は「その場しのぎ」になりがちで、型が本来の設計とズレると後段でバグになります。既定値の型は仕様通りに統一(文字なら文字、数なら数)しましょう。

“欠損=エラー”にしたい場面では使わない

必須項目は get で隠さず、[] で素直にエラーを出すほうが原因に早く辿り着けます。テスト時は KeyError を期待して設計します。


まとめ

dict.get は「欠損していても例外なく値を返す」ための基本メソッドです。デフォルトで None、必要なら既定値を指定でき、辞書を変更しません。必須なら []、任意なら get、辞書を育てるなら setdefault。falsy 誤判定を避ける、default の評価コストに注意する、型の一貫性を保つ——この要点を押さえれば、初心者でも安全で読みやすい辞書処理が書けます。

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