查看全课大纲(第 26 / 51 节)
  1. 1.Python 是什么?为什么值得学?
  2. 2.如何为 Python 编程准备一个“全家桶”环境?
  3. 3.Python 有哪几种执行方法?
  4. 4.行与缩进到底有什么用?
  5. 5.注释有什么用,怎么写?
  6. 6.变量:如何给数据起个好名字?
  7. 7.运算符的优先级和常见坑点是什么?
  8. 8.Python 中,数字和布尔值究竟有哪几种?
  9. 9.输入函数 `input()` 和文件读取 `open()` 怎么用?
  10. 10.如何将程序的结果展示给用户或保存下来?
  11. 11.CSV 文件怎么读怎么写才方便?
  12. 12.列表是什么,如何创建和访问它?
  13. 13.列表的修改操作,有哪些方法?
  14. 14.列表切片为什么能取到部分元素?排序和查找又该怎么用?
  15. 15.判断语句:如何让程序根据条件做不同的事?
  16. 16.for 循环如何遍历序列中的元素?
  17. 17.while 循环什么时候才会停?
  18. 18.while 循环的结束条件,你写对了吗?
  19. 19.循环中途想提前结束,怎么办?
  20. 20.`break` 和 `continue` 到底有什么区别?
  21. 21.列表推导式如何让代码更简洁高效?
  22. 22.字符串怎么定义、拼接和操作?
  23. 23.元组:为什么定义单个元素时要加逗号?
  24. 24.集合(set)怎么用?如何快速去重和做集合运算?
  25. 25.字典是什么,为什么比列表更方便?
  26. 26.字典的增删改查与遍历,如何避免 KeyError?
  27. 27.函数里的变量,为什么有的能用有的不能用?
  28. 28.在函数内部修改全局变量,为什么有时不生效?
  29. 29.函数里能修改全局变量吗?返回值怎么用?
  30. 30.匿名函数:如何用 lambda 快速定义简单函数?
  31. 31.面向对象编程是什么,为什么需要它?
  32. 32.类中的方法和属性到底怎么定义和使用?
  33. 33.如何控制对对象内部属性和方法的访问?
  34. 34.异常发生时,程序会怎样继续执行?
  35. 35.如何组织代码:包和模块
  36. 36.`if __name__ == '__main__'` 到底有什么用?
  37. 37.如何用 IDE 的 Debug 功能排查程序错误?
  38. 38.Matplotlib 绘图的第一步该做什么?
  39. 39.Figure 是什么,如何设置图形尺寸?
  40. 40.如何自定义 Matplotlib 的坐标轴?
  41. 41.如何为图表添加图例,让不同曲线一目了然?
  42. 42.饼图怎么画才能直观展示数据占比?
  43. 43.如何用 Matplotlib 绘制散点图?
  44. 44.柱状图怎么画?
  45. 45.如何使用 Matplotlib 绘制等高线图?
  46. 46.如何在 Matplotlib 中绘制子图?
  47. 47.zip 函数如何把多个列表“打包”在一起?
  48. 48.如何给可迭代对象加上索引?
  49. 49.random 模块如何生成随机数?
  50. 50.math 模块怎么用?
  51. 51.Counter 如何快速统计元素出现次数?

字典的增删改查与遍历,如何避免 KeyError?

约 11 分钟

小象实战讲义 · Python 编程从入门到实践

上一节我们学习了字典的基本概念和定义。字典的核心是“键-值”对,但光有定义还不够,我们还需要知道如何操作它。本节将系统学习字典的增、删、改、查以及遍历操作,并掌握如何安全地访问字典,避免程序因键不存在而崩溃。

💡 核心导读

  • 键的唯一性:字典中同一个键只能对应一个值,后定义的会覆盖先定义的。
  • 基础操作:使用 dict[key] = value 添加或修改元素;使用 del dict[key] 删除元素。
  • 安全访问:使用 in 关键字判断键是否存在,或使用 get() 方法获取值(可设默认值)。
  • 遍历字典:使用 keys()、values()、items() 方法分别遍历键、值或键值对。
  • 清空字典:使用 clear() 方法清空字典所有内容。

键的唯一性与覆盖规则

字典的核心功能是通过一个键(key)唯一地定位一个值(value)。同一个键只能出现一次。如果在定义字典时,为同一个键赋予了不同的值,后定义的值会覆盖先定义的值。

# 定义字典时,键"job"出现了两次
user_info = {"name": "悟空", "age": 100, "gender": "male", "job": "取经", "job": "偷桃"}
print(user_info["job"])
偷桃

可以看到,通过 "job" 查到的是“偷桃”。最终字典中只保留最后一个 "job": "偷桃" 这一项,所以定义和使用字典时要确保键的唯一性。

字典的增、删、改、查

字典是可变数据类型,我们可以方便地对其中的元素进行增加、删除、修改和查询。

添加与修改元素

语法都是 字典变量[键] = 值。如果该键不存在,则为添加新元素;如果该键已存在,则为修改其对应的值。

删除元素

使用 del 语句可以删除字典中指定的键值对,语法为 del 字典变量[键]。如果要删除的键在字典中不存在,会引发 KeyError 异常,导致程序崩溃。

# 初始字典
user_info = {"name": "悟空", "age": 100, "gender": "male", "job": "取经"}
print("初始字典:", user_info)

# 添加新元素:添加电话号码
user_info["tel"] = "13812345678"
print("添加电话后:", user_info)
print("当前字典长度(键值对数量):", len(user_info))

# 修改已有元素:悟空换了个"吉利"号码
user_info["tel"] = "13888888888"
print("修改电话后:", user_info)

# 删除元素:悟空嫌八戒老打电话
del user_info["tel"]
print("删除电话后:", user_info)
初始字典: {'name': '悟空', 'age': 100, 'gender': 'male', 'job': '取经'}
添加电话后: {'name': '悟空', 'age': 100, 'gender': 'male', 'job': '取经', 'tel': '13812345678'}
当前字典长度(键值对数量): 5
修改电话后: {'name': '悟空', 'age': 100, 'gender': 'male', 'job': '取经', 'tel': '13888888888'}
删除电话后: {'name': '悟空', 'age': 100, 'gender': 'male', 'job': '取经'}
# 错误示例:删除一个不存在的键
del user_info["address"]   # 会抛出 KeyError: 'address'

安全地访问字典:in 判断与 get() 方法

为了避免因键不存在而导致的程序异常,我们需要更安全的访问方式。

使用 in 判断键是否存在

在尝试访问或删除一个键之前,可以先判断它是否在字典中。in 只与字典中的所有键比较,不比较值。

使用 get() 方法获取值

get(key[, default]) 方法是更简洁、安全的查询方式:

  • 如果键存在,返回对应的值。
  • 如果键不存在,默认返回 None,而不会抛出异常。
  • 可以提供一个可选的 default 参数,当键不存在时,返回这个默认值。
user_info = {"name": "悟空", "age": 100, "gender": "male", "job": "取经"}

# 用 in 判断键是否存在
key_to_check = "tel"
if key_to_check in user_info:
    print("键 {} 存在,对应的值是:{}".format(key_to_check, user_info[key_to_check]))
else:
    print("键 {} 不存在".format(key_to_check))

# get:键不存在时返回 None
tel_value = user_info.get("tel")
print("get('tel') 的结果是:", tel_value)
print("结果类型是:", type(tel_value))

# get:键不存在时返回指定的默认值
print("get('tel', '10010') 的结果是:", user_info.get("tel", "10010"))

# get:键存在时正常返回值
print("get('name', '未知') 的结果是:", user_info.get("name", "未知"))
键 tel 不存在
get('tel') 的结果是: None
结果类型是: <class 'NoneType'>
get('tel', '10010') 的结果是: 10010
get('name', '未知') 的结果是: 悟空

遍历字典与清空

我们经常需要遍历字典中的所有内容。根据不同的需求,可以分别遍历键、值或键值对;遍历完成后,还可以用 clear() 一次性清空字典。

遍历所有的键(.keys())

keys() 方法取出字典的所有键,常用于 for 循环。循环中每次取出一个 key,再用这个 key 去查对应的 value。

遍历所有的值(.values())

如果只关心值、不关心键,可以使用 values() 方法。

遍历所有的键值对(.items())

items() 方法把键值对都取出来,每一项是一个 (键, 值) 元组,可以用下标 item[0]、item[1] 取键和值;也可以在 for 循环中直接用两个变量接收,这时变量名可以自己取(如 k、v)。

清空字典

clear() 方法会把字典中的所有元素清掉。空字典用一对什么都不带的花括号 {} 表示。

user_info = {"name": "悟空", "age": 100, "gender": "male", "job": "取经"}

print("遍历所有的键和对应的值:")
for key in user_info.keys():
    print("  {}: {}".format(key, user_info[key]))

print("遍历所有的值:")
for value in user_info.values():
    print("  {}".format(value))

print("遍历所有的键值对(元组形式):")
for item in user_info.items():
    print("  item = {},类型是 {}".format(item, type(item)))
    print("      键(item[0]) = {}".format(item[0]))
    print("      值(item[1]) = {}".format(item[1]))

print("直接解包键和值:")
for k, v in user_info.items():
    print("  {}: {}".format(k, v))

# 清空字典
user_info.clear()
print("清空后:", user_info)
遍历所有的键和对应的值:
  name: 悟空
  age: 100
  gender: male
  job: 取经
遍历所有的值:
  悟空
  100
  male
  取经
遍历所有的键值对(元组形式):
  item = ('name', '悟空'),类型是 <class 'tuple'>
      键(item[0]) = name
      值(item[1]) = 悟空
  item = ('age', 100),类型是 <class 'tuple'>
      键(item[0]) = age
      值(item[1]) = 100
  item = ('gender', 'male'),类型是 <class 'tuple'>
      键(item[0]) = gender
      值(item[1]) = male
  item = ('job', '取经'),类型是 <class 'tuple'>
      键(item[0]) = job
      值(item[1]) = 取经
直接解包键和值:
  name: 悟空
  age: 100
  gender: male
  job: 取经
清空后: {}

📝 动手练一练

假设你正在管理一个简单的学生成绩字典,键是科目名称,值是分数。

  1. 向字典中添加一门新课“化学”,成绩为 88 分。
  2. 发现“物理”的成绩登记错了,实际是 92 分,请修改。
  3. 使用 get() 方法查询“生物”的成绩,如果不存在则返回“未选修”。
  4. 使用 for 循环遍历这个字典,并按照“科目: 成绩”的格式打印出所有内容。
👉 点击查看参考答案
# 初始成绩单
scores = {"数学": 90, "英语": 85, "物理": 60}
print("初始成绩单:", scores)

# 1. 添加新课"化学"
scores["化学"] = 88
print("添加化学后:", scores)

# 2. 修改"物理"成绩
scores["物理"] = 92
print("修改物理后:", scores)

# 3. 安全查询"生物"成绩
print("生物成绩:", scores.get("生物", "未选修"))

# 4. 遍历并打印所有科目成绩
print("所有科目成绩如下:")
for subject, score in scores.items():
    print("  {}: {}".format(subject, score))
初始成绩单: {'数学': 90, '英语': 85, '物理': 60}
添加化学后: {'数学': 90, '英语': 85, '物理': 60, '化学': 88}
修改物理后: {'数学': 90, '英语': 85, '物理': 92, '化学': 88}
生物成绩: 未选修
所有科目成绩如下:
  数学: 90
  英语: 85
  物理: 92
  化学: 88

常见错误

错误写法现象或报错原因正确写法
del my_dict["key"](当 key 不存在时)KeyError: 'key'试图删除一个字典中不存在的键。先使用 if "key" in my_dict: 判断,确认存在再删除。
value = my_dict["key"](当 key 不存在时)KeyError: 'key'使用方括号 [] 访问不存在的键会直接报错。使用 value = my_dict.get("key") 或 my_dict.get("key", 默认值)。
if "悟空" in user_info: 想判断“悟空”是否在字典里结果总是 Falsein 只与字典中的所有键比较,不比较值。判断值用 "悟空" in user_info.values()。

小结

  1. 键唯一:字典中同一个键后定义的值会覆盖先定义的值。
  2. 增改同语法:dict[key] = value 既可添加新键值对,也可修改已有键的值。
  3. 删用 del:del dict[key] 用于删除指定键值对,但需确保键存在,否则会报 KeyError。
  4. 安全访问:使用 key in dict 判断键是否存在,或使用 dict.get(key, default) 安全获取值。
  5. 三种遍历:dict.keys() 遍历键,dict.values() 遍历值,dict.items() 遍历键值对(推荐用两个变量解包)。
  6. 清空字典:dict.clear() 方法可以快速清空字典所有内容。

📋 行动清单

  • 在示例代码中,尝试将 get() 方法的默认值从字符串换成数字 0,观察输出变化。
  • 将遍历字典的三种方式(keys()、values()、items())的代码都自己敲一遍,并理解其输出差异。
  • 故意写一行删除不存在键的代码,运行并观察 KeyError 的具体报错信息,加深印象。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 第3章代码包:字典(含1 个 Notebook)
    ZIP · 2KB
    下载