# 請問內層的字典可以不一樣長嗎?指有的有3鍵,有的有5鍵
# 答案是:可以的!巢狀字典中每個內層字典的長度可以不同,也就是說,有的學生可以有 3 科成績,有的學生有 5 科成績,完全沒問題。
# ✅ 合法範例(內層字典長度不同):
students = {
"annie": {"國文": 90, "數學": 95, "英文": 88},
"lydia": {"國文": 85, "數學": 91}, # 少了英文
"mary": {"國文": 80, "數學": 82, "英文": 84, "自然": 90, "社會": 87}
}
# 每個學生的科目數量都不同,但 Python 可以正常處理,只要你在取值時小心不要找不到不存在的鍵即可。
# ⚠️ 注意事項:避免找不到的錯誤
# 如果你寫:
print(students["lydia"]["英文"]) # 會錯誤!因為 lydia 沒有「英文」
# 會出現:
KeyError: '英文'
# ✅ 解法:用 .get() 比較安全
print(students["lydia"].get("英文", "沒有這科"))
# ➡️ 若有「英文」科目,就回傳分數;若沒有,就回傳 "沒有這科"
# 結果會是:
沒有這科
# 📘 小結
# 題目 答案
# 內層字典可以長度不同嗎? ✅ 可以!
# 取值時要注意什麼? ❗ 可能沒有某個科目,會出現 KeyError
# 怎麼避免? 用 dict.get("鍵", 預設值)
# 如果我要在students 新增= "kay": {"國文": 80, "數學": 75, "英文": 66} 程式要怎麼寫
# 這就是字典的 新增項目操作!
✅ 方法一:直接指定一個新鍵加上字典
students["kay"] = {"國文": 80, "數學": 75, "英文": 66}
# 這一行就會把 kay 加入到 students 裡面。
# 📦 操作前後示範:
# 原本的 students 字典
students = {
"annie": {"國文": 90, "數學": 95, "英文": 88},
"lydia": {"國文": 85, "數學": 91},
}
# 新增 kay
students["kay"] = {"國文": 80, "數學": 75, "英文": 66}
# 印出來確認
print(students)
# 輸出會是:
{
"annie": {"國文": 90, "數學": 95, "英文": 88},
"lydia": {"國文": 85, "數學": 91},
"kay": {"國文": 80, "數學": 75, "英文": 66}
}
# ✅ 方法二:使用 update()(效果一樣)
students.update({
"kay": {"國文": 80, "數學": 75, "英文": 66}
})
# 這種寫法適合一次加入多個人:
students.update({
"kay": {"國文": 80, "數學": 75, "英文": 66},
"mary": {"國文": 88, "數學": 92, "英文": 90}
})
# 如果我要在 mary 新增 生物:70 也是用.update()嗎?
# 沒錯!要在 mary 的成績中新增 "生物": 70,你也可以使用 .update() 方法,但這次是針對內層的字典來更新。
# ✅ 寫法如下:
students["mary"].update({"生物": 70})
# 📌 補充說明:
# 假設 students["mary"] 原本是這樣:
"mary": {"國文": 80, "數學": 82, "英文": 84}
# 執行完 .update() 後就會變成:
"mary": {"國文": 80, "數學": 82, "英文": 84, "生物": 70}
# ✅ 也可以用這個寫法(效果一樣):
students["mary"]["生物"] = 70
# 這是更直接的方式,適合只加一個項目。
# 🧠 小結
# 功能 寫法
# 加一個學生 students["kay"] = {...} 或 students.update({...})
# 給某位學生加一科 students["mary"]["生物"] = 70 或 students["mary"].update({...})
# 如果你想要讓使用者輸入科目與成績並自動加入,也可以擴展成互動式程式,我可以幫你寫一個小工具哦 😄
# ["mary"]如果不存在,直接加是會出現錯誤的
# 💯 沒錯,完全正確!
# ❗ 情況說明,如果你嘗試執行:
students["mary"]["生物"] = 70
# 但 students["mary"] 根本不存在,程式就會報錯:
KeyError: 'mary'
# ✅ 安全做法:先檢查是否存在
# 方法一:用 in 判斷
if "mary" not in students:
students["mary"] = {}
students["mary"]["生物"] = 70
# 這樣就可以避免錯誤。如果 "mary" 不存在,就先建立一個空字典。
# 方法二:用 setdefault()(更精簡)
students.setdefault("mary", {})["生物"] = 70
# 這行的意思是:
# 如果 "mary" 存在,就使用她的成績字典
# 如果 "mary" 不存在,就先建立一個空字典給她
# 然後再新增 "生物": 70
# 這種寫法特別適合「可能有或沒有」的狀況。
# 🧠 總結對照表:
# 目的 安全做法
# 確保某個學生存在 students.setdefault("mary", {})
# 加一科成績給某學生. students["mary"]["生物"] = 70(前提是 mary 已存在)
# 一次完成兩件事 students.setdefault("mary", {})["生物"] = 70 ✅
# 如果你想讓使用者不管有沒有這個人都可以加資料,setdefault() 是最安全簡潔的方式。😊
# 使用.get會要注意資料的形態嗎?
students["lydia"].get("英文", "沒有這科")
# 是的,使用 .get() 雖然很安全,不會讓程式報錯,但你要注意它回傳的資料型態,這點很重要!
# 🔍 .get() 用法回顧:
students["lydia"].get("英文", "沒有這科")
# 這段程式碼會:
# 嘗試取得 "lydia" 的 "英文" 分數
# 如果沒有 "英文" 這科目,就回傳字串 "沒有這科"
# 🧠 所以你要注意的重點是:
# .get() 回傳值的型別可能不同!
# 📌 如果資料存在:
score = students["lydia"].get("英文", "沒有這科")
# 假設英文成績是 90
# score 會是 int 型態:90
# ⚠️ 如果資料不存在:
score = students["lydia"].get("生物", "沒有這科")
# score 會是 str 型態:"沒有這科"
# 這會導致一個常見問題:
if students["lydia"].get("生物", 0) > 60:
print("及格")
# 如果 "生物" 不存在,這行會是:
0 > 60 # ✔️ 不會錯
# 但如果你用:
students["lydia"].get("生物", "沒有這科") > 60
# 會變成:
"沒有這科" > 60 # ❌ TypeError:str 和 int 不能比大小!
# ✅ 解決建議
# 數值預設值時,請用數值型別:
score = students["lydia"].get("生物", 0) # 安全比大小
# 要回傳說明文字時,請記得確認類型:
score = students["lydia"].get("生物")
if score is None:
print("沒有這科")
else:
print(f"分數是:{score}")
# 🧠 小結:
# 情境 建議寫法 備註
# 需要安全取值(數字) .get("科目", 0) 回傳型別一致(int)
# 想回傳文字說明 .get("科目", "沒有這科") 但要小心之後別做數字運算
# 判斷是否有該科目 if "英文" in students["lydia"]: 最直接的方法