辞書.get() / 辞書.setdefault()
| 対応: | Python 2(2000) |
|---|
辞書から安全にキーを取得したり、キーが存在しない場合のデフォルト値を設定するメソッドです。『KeyError』を防ぐために重要です。
構文
# キーに対応する値を返す。キーが存在しない場合はデフォルト値を返す 辞書.get(キー, デフォルト値=None) # キーが存在しない場合はデフォルト値を設定してから返す。キーが存在する場合は既存の値を返す 辞書.setdefault(キー, デフォルト値=None)
関数一覧
| メソッド | 概要 |
|---|---|
| dict.get(key, default=None) | キーが存在する場合はその値を、存在しない場合は default を返します。辞書は変更されません。 |
| dict.setdefault(key, default=None) | キーが存在する場合はその値を返します。キーが存在しない場合は辞書に key: default を追加して default を返します。 |
サンプルコード
dict_get_setdefault.py
# get() でキーが存在しなくてもエラーにならずに取得
person = {"name": "user1", "age": 37, "city": "east_district"}
# 存在するキーを取得
print(person.get("name")) # user1
print(person.get("age")) # 37
# 存在しないキーを get() で取得すると None が返る
print(person.get("email")) # None
# デフォルト値を指定
print(person.get("email", "未登録")) # 未登録
print(person.get("phone", "000-0000")) # 000-0000
# get() と [] の違い
# person["email"] # KeyError が発生します。
# person.get("email") # エラーなし、None を返す
# 設定値を元に処理を分岐する実用例
config = {"debug": True, "timeout": 30}
log_level = config.get("log_level", "INFO") # デフォルトは "INFO"
print(f"ログレベル: {log_level}") # ログレベル: INFO
# setdefault() でキーが存在しない場合だけ値を設定
user = {"name": "user2"}
user.setdefault("role", "guest") # "role" がないので設定される
print(user) # {'name': 'user2', 'role': 'guest'}
user.setdefault("role", "admin") # "role" がすでにあるので変更されない
print(user) # {'name': 'user2', 'role': 'guest'}(admin にならない)
# setdefault() で辞書の値にリストを使う定番パターン
# グループ分けに便利な「辞書の値がリスト」の実装
members_by_org = {}
items = [
("team_x", "user1"), ("team_y", "user2"), ("team_x", "user3"),
("team_z", "user4"), ("team_y", "user5")
]
for org, name in items:
members_by_org.setdefault(org, []).append(name)
print(members_by_org)
# {'team_x': ['user1', 'user3'], 'team_y': ['user2', 'user5'], 'team_z': ['user4']}
# 同じことを collections.defaultdict でも実現できる
from collections import defaultdict
members_by_org2 = defaultdict(list)
for org, name in items:
members_by_org2[org].append(name)
print(dict(members_by_org2)) # 同じ結果になります。
# 名前の出現回数をカウントする例
names = ["user1", "user2", "user1", "user3", "user2", "user1"]
count = {}
for name in names:
count[name] = count.get(name, 0) + 1
print(count) # {'user1': 3, 'user2': 2, 'user3': 1}
実行すると次のように出力されます。
python3 dict_get_setdefault.py
user1
37
None
未登録
000-0000
ログレベル: INFO
{'name': 'user2', 'role': 'guest'}
{'name': 'user2', 'role': 'guest'}
{'team_x': ['user1', 'user3'], 'team_y': ['user2', 'user5'], 'team_z': ['user4']}
{'team_x': ['user1', 'user3'], 'team_y': ['user2', 'user5'], 'team_z': ['user4']}
{'user1': 3, 'user2': 2, 'user3': 1}
よくあるミス
よくあるミス1: getのデフォルト値が毎回生成されない
『get(key, default)』のデフォルト値は、キーが存在しなくても常に評価されます。デフォルト値の生成コストが高い場合は、条件分岐か『setdefault()』を使います。
members = {'user1': 'team_x', 'user2': 'team_y'}
# このコードはmemberに'user3'がなくても [] が毎回作られる(コストは小さいが)
result = members.get('user3', [])
# setdefault: キーがない場合のみデフォルト値を設定してキーを追加する
members.setdefault('user3', 'team_z')
print(members['user3']) # 'team_z'(キーが追加された)
# 既存キーには影響しない
members.setdefault('user1', 'team_w') # 既存なので変更なし
print(members['user1']) # 'team_x'(変わらない)
よくあるミス2: KeyErrorと[]アクセスの混同
存在しないキーに『[]』でアクセスすると『KeyError』が発生します。安全に取得するには『get()』を使います。
members = {'user1': 'team_x', 'user2': 'team_y'}
# 存在しないキーにアクセスするとKeyError
try:
org = members['user3'] # KeyError: 'user3'
except KeyError:
print('キーが見つかりません')
次のように記述します。
# get() でデフォルト値を返す
org = members.get('user3', '不明')
print(org) # '不明'(エラーなし)
概要
辞書の値を取得するとき、存在しないキーに『[]』でアクセスすると『KeyError』が発生します。キーが存在するかどうか不確かな場合は、必ず『get()』を使うか、事前に『in』演算子で確認してからアクセスします。
『setdefault()』と『get()』の最大の違いは、辞書を変更するかどうかです。『setdefault()』はキーが存在しない場合に辞書を変更してデフォルト値を登録します。これを利用して「初回アクセス時に空リストを設定し、以後その場所にデータを追加する」というパターンが頻繁に使われます。
単語のカウントや集計には、標準ライブラリの『collections.Counter』がより簡潔です。辞書の更新については『辞書.update() / 辞書.pop()』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。