Python 入門教學:搞懂 defaultdict 與 setdefault() 的差別

加入好友
加入社群
Python 入門教學:搞懂 defaultdict 與 setdefault() 的差別 - 儲蓄保險王

在 Python 裡,當我們想把資料「分類整理」時,常常會遇到這種需求:

  • 如果某個 key 還不存在,就先建立一個空清單
  • 然後把資料加進去

例如,我們想把學生依照班級分組:

students = [
    ("A班", "小明"),
    ("A班", "小華"),
    ("B班", "小美"),
    ("B班", "阿強"),
]

最後希望變成:

{
    "A班": ["小明", "小華"],
    "B班": ["小美", "阿強"]
}

這時你很可能會遇到兩種寫法:

  • defaultdict
  • setdefault()

這篇文章會用簡化例子帶你看懂它們的差別。


一、先看最普通的寫法

如果不用 defaultdictsetdefault(),你可能會這樣寫:

students = [
    ("A班", "小明"),
    ("A班", "小華"),
    ("B班", "小美"),
    ("B班", "阿強"),
]

groups = {}

for class_name, student in students:
    if class_name not in groups:
        groups[class_name] = []
    groups[class_name].append(student)

print(groups)

輸出:

Python 入門教學:搞懂 defaultdict 與 setdefault() 的差別 - 儲蓄保險王

這完全沒問題,但會稍微有點囉嗦,因為每次都要先檢查:

if class_name not in groups:
    groups[class_name] = []

所以 Python 提供了更方便的工具。


二、什麼是 setdefault()

setdefault() 是一般 dict 就有的方法。

它的概念是:

如果 key 不存在,就放入預設值;如果已存在,就直接使用原本的值。

範例

students = [
    ("A班", "小明"),
    ("A班", "小華"),
    ("B班", "小美"),
    ("B班", "阿強"),
]

groups = {}

for class_name, student in students:
    groups.setdefault(class_name, []).append(student)

print(groups)

輸出:

Python 入門教學:搞懂 defaultdict 與 setdefault() 的差別 - 儲蓄保險王

三、setdefault() 拆開來看

這行:

groups.setdefault(class_name, []).append(student)

可以理解成:

  1. 檢查 class_name 這個 key 在不在 groups
  2. 如果不在,就建立:
groups[class_name] = []
  1. 然後回傳這個 list
  2. 最後再 .append(student)

所以它等於下面這段:

if class_name not in groups:
    groups[class_name] = []
groups[class_name].append(student)

四、什麼是 defaultdict

defaultdict 來自 collections 模組,需要先 import:

from collections import defaultdict

它是一種「加強版字典」。

你可以在建立字典時,就先告訴 Python:

如果 key 不存在,請自動幫我建立一個空 list。

範例

from collections import defaultdict

students = [
    ("A班", "小明"),
    ("A班", "小華"),
    ("B班", "小美"),
    ("B班", "阿強"),
]

groups = defaultdict(list)

for class_name, student in students:
    groups[class_name].append(student)

print(groups)

輸出:

Python 入門教學:搞懂 defaultdict 與 setdefault() 的差別 - 儲蓄保險王

如果你想把它變回一般字典,也可以這樣做:

print(dict(groups))

輸出:

Python 入門教學:搞懂 defaultdict 與 setdefault() 的差別 - 儲蓄保險王

五、defaultdict(list) 是什麼意思

這行:

groups = defaultdict(list)

意思是:

  • 這是一個 defaultdict
  • 當你讀取不存在的 key 時
  • 它會自動建立一個 list()
  • 也就是空清單 []

所以這樣寫不會報錯:

groups["A班"].append("小明")

即使 "A班" 一開始不存在,它也會自動先變成:

groups["A班"] = []

然後再 append。


六、兩者的差別

1. setdefault() 是「每次遇到 key 時」再決定預設值

groups.setdefault(class_name, []).append(student)

你是每次在操作時,告訴 Python:

  • 這個 key 沒有的話,就給它 []

2. defaultdict 是「建立字典時」就先定好規則

groups = defaultdict(list)

你一開始就告訴 Python:

  • 只要有不存在的 key,就自動給我 []

七、簡單比較表

Python 入門教學:搞懂 defaultdict 與 setdefault() 的差別 - 儲蓄保險王

八、哪個比較好懂?

對初學者來說:

  • 如果你只想快速完成任務,setdefault() 很方便
  • 如果你常做分組整理,defaultdict 更直觀

setdefault()

groups = {}
for class_name, student in students:
    groups.setdefault(class_name, []).append(student)

defaultdict

from collections import defaultdict

groups = defaultdict(list)
for class_name, student in students:
    groups[class_name].append(student)

很多人會覺得 defaultdict 版更乾淨,因為主程式邏輯比較單純。


九、要注意的一個地方

defaultdict 有一個特性:

只要你存取不存在的 key,它就會自動建立出來。

例如:

from collections import defaultdict

d = defaultdict(list)

print(d["X班"])
print(d)

輸出:

Python 入門教學:搞懂 defaultdict 與 setdefault() 的差別 - 儲蓄保險王

注意喔,雖然你只是 print(d["X班"]),但 "X班" 已經真的被加進字典了。


而一般 dictget() 不會這樣:

d = {}

print(d.get("X班"))
print(d)

輸出:

Python 入門教學:搞懂 defaultdict 與 setdefault() 的差別 - 儲蓄保險王

所以如果你不希望「只是讀一下就新增 key」,
那就要特別留意 defaultdict 的這個行為。

推薦hahow線上學習python: https://igrape.net/30afN

加入好友
加入社群
Python 入門教學:搞懂 defaultdict 與 setdefault() 的差別 - 儲蓄保險王

儲蓄保險王

儲蓄險是板主最喜愛的儲蓄工具,最喜愛的投資理財工具則是ETF,最喜愛的省錢工具則是信用卡

You may also like...

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *