🐍 Python
collections.defaultdict で初期値を自動化する
通常の辞書は存在しないキーにアクセスするとKeyErrorになりますが、collections.defaultdictを使うと、存在しないキーにアクセスした瞬間に自動で初期値が作られます。カウントやグループ化のたびにsetdefault()を書く手間を省けます。
from collections import defaultdict
dd = defaultdict(int) # 存在しないキーはint()、つまり0になる
dd = defaultdict(list) # 存在しないキーはlist()、つまり[]になる
# カウント処理がシンプルになる
from collections import defaultdict
dd = defaultdict(int)
for ch in "mississippi":
dd[ch] += 1 # 初回アクセスでも自動的に0から始まる
print(dict(dd))
# {'m': 1, 'i': 4, 's': 4, 'p': 2}
# グループ化処理もsetdefault()無しで書ける
from collections import defaultdict
dd2 = defaultdict(list)
for word in ["apple", "avocado", "banana", "blueberry"]:
dd2[word[0]].append(word)
print(dict(dd2))
# {'a': ['apple', 'avocado'], 'b': ['banana', 'blueberry']}
# 注意: 「読んだだけ」でもキーが追加される
from collections import defaultdict
dd2 = defaultdict(list)
dd2["a"] = ["apple"]
print(dd2["z"]) # 存在しないキーを読んだだけ
# []
print(dict(dd2))
# {'a': ['apple'], 'z': []} ← 'z'キーが追加されてしまっている
# 通常のdictなら同じアクセスはKeyErrorになる
plain = {}
try:
plain["z"] += 1
except KeyError as e:
print("KeyError:", e)
# KeyError: 'z'
defaultdictの引数
- default_factory
- 引数を取らずに呼び出せる関数(
int、list、set、あるいはlambda: "N/A"のような自作の関数)を渡す。存在しないキーにアクセスした際、この関数を呼んだ結果が初期値になる
💡 AIコードレビュー観点:存在確認だけのつもりのアクセスに注意
if dd["key"]:のように、値の中身を条件式で確認するだけのつもりのコードでも、defaultdictではその時点で"key"が辞書に追加されてしまいます。「存在するかどうかだけ知りたい」場合は"key" in ddを使い、dd["key"]のような角括弧アクセスは避けましょう。AIが生成したコードでdefaultdictに対して読み取り専用のつもりの[]アクセスが多用されていたら、辞書のサイズが意図せず膨張していないか確認する価値があります。