什麼是 defaultdict
?
defaultdict
是 Python 標準庫 collections
裡的一種字典(dict)子類。
它解決了一個常見問題:存取不存在的 key 時不會報錯,還能自動幫你建立預設值!
為什麼要用 defaultdict
?
假設你要做一個字典,統計每個字母出現次數,普通寫法如下:
counts = {}
for ch in 'banana':
if ch not in counts:
counts[ch] = 0
counts[ch] += 1
這種寫法很常見,但每次都要檢查 key 是否存在。
用 defaultdict
的超簡潔寫法
from collections import defaultdict
counts = defaultdict(int) # int() 預設值是 0
for ch in 'banana':
counts[ch] += 1
print(counts) # defaultdict(<class 'int'>, {'b': 1, 'a': 3, 'n': 2})
輸出結果:

優點:不用再判斷 key 是否存在!
defaultdict
的常見用法
1. 統計次數
words = ['cat', 'dog', 'cat', 'dog', 'cat', 'fish']
counter = defaultdict(int)
for word in words:
counter[word] += 1
print(counter)
輸出結果:

2. 統計多個值(如字典的 value 是 list)
group = defaultdict(list)
for name, group_id in [('Amy', 1), ('Ben', 2), ('Carl', 1)]:
group[group_id].append(name)
print(group) # defaultdict(<class 'list'>, {1: ['Amy', 'Carl'], 2: ['Ben']})
輸出結果:

3. 巢狀結構(自動建多層 dict)
初階寫法(只能一層)
d = defaultdict(dict)
d['a']['b'] = 1 # 只會自動建立 'a' 這一層
# d['a']['b']['c'] = 2 # 會報錯,因為 d['a']['b'] 只是普通 dict
輸出結果:

進階:無限巢狀 defaultdict
def tree():
return defaultdict(tree)
nested = tree()
nested['foo']['bar']['baz'] = 123
print(nested['foo']['bar']['baz']) # 123
輸出結果:

如何把 defaultdict 轉回普通 dict(遞迴轉換)
defaultdict
不是序列化友善的類型,如果你要 dump 成 JSON,
可以用遞迴方式轉成普通 dict:
# 沒有 else
def to_dict(d):
if isinstance(d, defaultdict):
return {k: to_dict(v) for k, v in d.items()}
return d
# 有 else,邏輯比較清楚
def to_dict(d):
if isinstance(d, defaultdict):
return {k: to_dict(v) for k, v in d.items()}
else:
return d
實證:

實用場景小結
- 字頻/計數統計(int)
- 群組分桶(list/set)
- 多層巢狀資料(遞迴 tree)
小提示
defaultdict(int)
→ 預設 0defaultdict(list)
→ 預設空列表defaultdict(set)
→ 預設空集合defaultdict(lambda: 'Hello!')
→ 預設自定義值
結論
defaultdict
是 Pythonic 寫法的好幫手,
讓你的程式更簡潔、更健壯、更易維護!
推薦hahow線上學習python: https://igrape.net/30afN
nested = defaultdict(defaultdict) #無法無限遞迴
實際上不能達到「多層巢狀自動建立」的效果!
為什麼?
因為:
defaultdict(defaultdict)
的意思是:當 key 不存在時,會呼叫「預設工廠」defaultdict()
。- 但沒給
defaultdict
的型別參數,所以會報錯:

- 更重要的是,即使你寫成
defaultdict(dict)
,
也只會自動建立一層普通 dict,下一層不會是 defaultdict!
正確的遞迴巢狀 defaultdict 寫法
你應該用函式遞迴來建立每一層:
from collections import defaultdict
def tree():
return defaultdict(tree)
nested = tree()
nested['a']['b']['c'] = 123 # 每層都自動建立
輸出結果:

小結
defaultdict(defaultdict)
❌ 錯誤寫法,不支援多層自動巢狀defaultdict(dict)
❌ 只會自動建立一層defaultdict(tree)
✅ 無限巢狀,推薦
視覺化差異

重點:要實現多層巢狀自動建立,必須用遞迴函式當工廠,不是直接 defaultdict(defaultdict)。
推薦hahow線上學習python: https://igrape.net/30afN
近期留言