第 1-10 课:字典
一、本课目标
完成本课后,你应该能够:
- 解释键值对是什么;
- 创建字典和空字典;
- 使用键读取字典中的值;
- 使用
get()安全读取数据; - 添加和修改键值对;
- 使用
pop()、del和clear()删除数据; - 使用
keys()、values()和items(); - 遍历字典的键、值和键值对;
- 使用嵌套字典表达分组配置;
- 使用列表保存多个字典记录;
- 理解字典键的基本限制;
- 判断列表、元组和字典的适用场景。
二、前置知识
开始本课前,你应该已经掌握:
- 字符串、数字和布尔值;
- 列表与元组;
if条件判断;for循环;in成员判断;- f-string 格式化输出。
三、为什么需要字典
上一课可以使用元组保存 Agent 配置:
agent_config = ("gpt-5", 0.7, 2000, True)
读取配置时依赖固定位置:
model_name = agent_config[0]
temperature = agent_config[1]
代码阅读者必须记住每个位置的含义。
字典(Dictionary,类型名为 dict)使用名称描述每一项数据:
agent_config = {
"model": "gpt-5",
"temperature": 0.7,
"max_tokens": 2000,
"enabled": True,
}
读取时直接使用字段名称:
print(agent_config["model"])
print(agent_config["temperature"])
这种代码更容易理解,也适合表达配置、用户、产品和接口数据。
四、键值对
字典中的每一项由键和值组成,称为键值对(Key-Value Pair):
"model": "gpt-5"
- 键(Key):
"model",用于定位数据; - 值(Value):
"gpt-5",是真正保存的数据。
键和值之间使用英文冒号 :,多个键值对之间使用英文逗号分隔。
五、创建字典
5.1 创建包含数据的字典
agent_config = {
"model": "gpt-5",
"temperature": 0.7,
"max_tokens": 2000,
"enabled": True,
}
多行字典的最后一个键值对后保留逗号,是常见的代码风格,便于以后增加字段和查看 Git 差异。
5.2 创建空字典
empty_config = {}
也可以写成:
empty_config = dict()
初学阶段优先使用 {}。
5.3 查看类型与长度
print(type(agent_config))
print(len(agent_config))
len() 返回键值对数量。
六、使用方括号读取值
model_name = agent_config["model"]
方括号中写的是键,不是数字位置。
如果键不存在:
agent_config["timeout"]
会产生 KeyError,中文可以理解为“指定键不存在”。
适用场景:确定该键必须存在,缺少时应当暴露错误。
七、使用 get() 安全读取
timeout = agent_config.get("timeout")
键不存在时,默认返回 None,不会产生 KeyError。
None 表示“没有值”或“空值”,它是 Python 中一个特殊对象,不是字符串 "None"。
可以设置默认值:
timeout = agent_config.get("timeout", 30)
如果 timeout 不存在,返回整数 30。
需要注意:get() 返回默认值不会自动把这个键写入字典。
八、判断键是否存在
in 用于判断字典中是否存在指定键:
if "model" in agent_config:
print(agent_config["model"])
判断不存在:
if "timeout" not in agent_config:
print("尚未配置超时时间")
默认情况下,in 检查的是键,不是值:
print("model" in agent_config) # True
print("gpt-5" in agent_config) # False
九、添加和修改键值对
字典是可变对象,可以添加和修改数据。
9.1 添加新键
agent_config["timeout"] = 30
如果键原来不存在,就会新增。
9.2 修改已有键
agent_config["temperature"] = 0.3
如果键已经存在,就会覆盖旧值。
相同语法会根据键是否存在决定“新增”还是“修改”。
十、使用 update() 更新多个字段
agent_config.update({
"temperature": 0.2,
"timeout": 60,
})
update() 会:
- 修改已存在的键;
- 添加不存在的键。
它直接修改原字典,通常不返回更新后的字典。
十一、删除键值对
11.1 pop() 删除并返回值
removed_timeout = agent_config.pop("timeout")
键不存在时会产生 KeyError。可以提供默认值:
removed_timeout = agent_config.pop("timeout", None)
这样键不存在时返回 None。
11.2 del 删除指定键
if "timeout" in agent_config:
del agent_config["timeout"]
del 不返回被删除的值。
11.3 clear() 清空字典
agent_config.clear()
字典变量仍然存在,但键值对数量变为 0。
十二、获取键、值和键值对
12.1 keys()
config_keys = agent_config.keys()
得到所有键。
12.2 values()
config_values = agent_config.values()
得到所有值。
12.3 items()
config_items = agent_config.items()
得到所有键值对。遍历字典时最常用。
这些方法返回的是字典视图(Dictionary View),不是普通列表。现阶段可以直接遍历;确实需要列表时,可以使用 list() 转换。
十三、遍历字典
13.1 遍历键
for key in agent_config:
print(key)
也可以明确写成:
for key in agent_config.keys():
print(key)
13.2 遍历值
for value in agent_config.values():
print(value)
13.3 同时遍历键和值
for key, value in agent_config.items():
print(f"{key}:{value}")
items() 每次提供一个包含键和值的二元素元组,再通过元组解包分别交给 key 和 value。
十四、字典是否有顺序
现代 Python 字典会保留键值对的插入顺序。
config = {
"model": "gpt-5",
"temperature": 0.7,
"enabled": True,
}
遍历时通常按照写入顺序得到这些键。
但是字典的核心用途仍然是“通过键查找值”,不应依赖数字索引访问。字典不支持:
config[0]
除非数字 0 本身就是一个真实的键。
十五、字典键必须唯一
一个字典中不能同时存在两个相同的键:
config = {
"model": "gpt-5",
"model": "o3",
}
后面的值会覆盖前面的值,最终 model 是 "o3"。
因此,字典不能依靠重复键保存多条同名记录。
十六、什么数据可以作为键
字典键必须是可哈希(Hashable)的对象。初学阶段可以记住:常见不可变类型通常可以作为键。
常见可用键:
- 字符串;
- 整数;
- 浮点数;
- 布尔值;
- 只包含不可变元素的元组。
列表不能作为键:
invalid_dict = {["Python", "FastAPI"]: "工具"}
会产生 TypeError,因为列表可变。
实际业务中最常用字符串键,含义清晰,也方便与 JSON 和接口数据对应。
十七、嵌套字典
字典的值可以是另一个字典:
agent_config = {
"model": {
"name": "gpt-5",
"temperature": 0.7,
},
"runtime": {
"timeout": 30,
"enabled": True,
},
}
读取嵌套值:
model_name = agent_config["model"]["name"]
timeout = agent_config["runtime"]["timeout"]
第一组方括号取得内部字典,第二组方括号从内部字典读取数据。
嵌套层级过深会降低可读性。真实项目应根据业务结构合理分组。
十八、列表中保存字典
如果要保存多个 Agent,可以使用列表存放多个字典:
agents = [
{"name": "代码助手", "model": "gpt-5", "enabled": True},
{"name": "搜索助手", "model": "o3", "enabled": False},
]
遍历:
for agent in agents:
print(f"{agent['name']}:{agent['model']}")
可以理解为:
- 列表负责保存多条记录;
- 每个字典负责描述一条记录的字段。
这种结构在接口返回的 JSON 数据中非常常见。
十九、字典中保存列表
字典的值也可以是列表:
agent = {
"name": "代码助手",
"tools": ["搜索", "计算", "写作"],
}
添加一个工具:
agent["tools"].append("代码执行")
这里先读取 tools 对应的列表,再调用列表的 append()。
二十、字典复制
直接赋值不会创建独立字典:
original_config = {"model": "gpt-5"}
alias_config = original_config
alias_config["model"] = "o3"
两个变量会看到同一个修改结果。
简单字典可以使用 copy():
copied_config = original_config.copy()
copied_config["model"] = "o3"
这仍然是浅复制。字典内部如果包含列表或字典,内部对象仍可能共享。深复制属于进阶内容。
二十一、列表、元组和字典如何选择
列表
适合保存多个同类、有顺序、数量可能变化的数据:
tools = ["搜索", "计算", "写作"]
元组
适合保存固定结构、创建后不希望变化的数据:
position = (116.4, 39.9)
字典
适合保存带字段名称的数据:
agent = {"name": "代码助手", "model": "gpt-5"}
真实程序通常会组合使用三种结构。
二十二、运行本课示例
在 PowerShell 中执行:
cd D:\Code\Python\01_python基础\1_10_字典
python dictionaries.py
示例无需用户输入,会展示字典的创建、读取、增删改查、遍历、嵌套和复制。
二十三、常见错误
23.1 使用不存在的键
确定键不一定存在时,可以使用 get() 或先使用 in 判断。
23.2 误以为 in 检查值
默认情况下,in 检查的是键。
23.3 字典键重复
相同键只能保留一个值,后面的值会覆盖前面的值。
23.4 使用列表作为键
列表可变,不能作为字典键。
23.5 遍历时直接修改字典大小
遍历字典期间直接添加或删除键,可能产生运行错误。需要修改结构时,可以先记录目标,循环结束后再修改。
23.6 直接赋值误认为复制
backup = original 不会创建独立字典。
二十四、课堂练习
打开 practice.py,完成“Agent 配置管理器”。
运行命令:
python practice.py
练习会要求你创建配置、读取默认值、修改字段、删除字段、遍历数据,并处理嵌套字典和 Agent 列表。
二十五、思考题
- 字典与元组相比,读取配置时有什么优势?
- 方括号读取与
get()有什么区别? in默认判断字典的键还是值?- 为什么字典键必须唯一?
- 为什么列表不能作为字典键?
items()遍历时为什么可以使用两个变量?- 列表中保存字典适合表达什么数据?
二十六、本课小结
- 字典使用键值对保存数据;
- 键用于定位数据,值是真正保存的内容;
- 方括号适合读取必须存在的键;
get()可以安全读取并提供默认值;- 字典是可变对象,可以增删改键值对;
keys()、values()、items()提供不同遍历方式;- 键必须唯一且可哈希;
- 字典可以嵌套,也可以与列表组合;
- 字段明确的数据通常适合使用字典。
二十七、验收标准
- 能创建字典和空字典;
- 能使用方括号和
get()读取值; - 能安全添加、修改和删除键值对;
- 能判断键是否存在;
- 能遍历键、值和键值对;
- 能使用嵌套字典;
- 能使用列表保存多个字典;
- 能解释常见字典键限制;
- 能完成并运行
practice.py; - 能回答七道思考题。