feat(python基础): 新增字典教学课程

This commit is contained in:
zhiye.sun
2026-07-29 16:31:08 +08:00
parent 4181826067
commit b5023b8e25
4 changed files with 801 additions and 5 deletions

View File

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

View File

@@ -0,0 +1,118 @@
# 第 1-10 课示例:字典
#
# 本文件使用 Agent 配置作为统一示例,演示字典的主要操作。
# 示例无需用户输入,可以直接运行并对照注释观察结果。
# 一、创建字典并读取字段
agent_config = {
"model": "gpt-5",
"temperature": 0.7,
"max_tokens": 2000,
"enabled": True,
}
print(f"完整配置:{agent_config}")
print(f"配置字段数量:{len(agent_config)}")
print(f"模型名称:{agent_config['model']}")
# 二、使用 get() 安全读取
# timeout 不存在,因此返回指定的默认值 30。
timeout = agent_config.get("timeout", 30)
print(f"超时时间:{timeout}")
# 三、添加和修改字段
agent_config["timeout"] = 60
agent_config["temperature"] = 0.3
print(f"添加和修改后的配置:{agent_config}")
# 四、使用 update() 更新多个字段
agent_config.update({
"temperature": 0.2,
"retries": 3,
})
print(f"批量更新后的配置:{agent_config}")
# 五、删除字段
# pop() 返回被删除的值;提供默认值可以避免键不存在时报错。
removed_retries = agent_config.pop("retries", None)
print(f"被删除的重试次数:{removed_retries}")
if "timeout" in agent_config:
del agent_config["timeout"]
print(f"删除后的配置:{agent_config}")
# 六、遍历键、值和键值对
print("所有键:")
for key in agent_config.keys():
print(key)
print("所有值:")
for value in agent_config.values():
print(value)
print("所有键值对:")
for key, value in agent_config.items():
print(f"{key}{value}")
# 七、嵌套字典
nested_config = {
"model": {
"name": "gpt-5",
"temperature": 0.7,
},
"runtime": {
"timeout": 30,
"enabled": True,
},
}
print(f"嵌套模型名称:{nested_config['model']['name']}")
print(f"嵌套超时时间:{nested_config['runtime']['timeout']}")
# 八、列表中保存多个字典
agents = [
{"name": "代码助手", "model": "gpt-5", "enabled": True},
{"name": "搜索助手", "model": "o3", "enabled": False},
]
for agent in agents:
# 使用已经学过的普通条件判断,把布尔值转换成更容易阅读的中文状态。
if agent["enabled"]:
status_text = "启用"
else:
status_text = "停用"
print(f"{agent['name']}{agent['model']},状态:{status_text}")
# 九、字典中保存列表
agent_profile = {
"name": "代码助手",
"tools": ["搜索", "计算"],
}
agent_profile["tools"].append("写作")
print(f"Agent 工具:{agent_profile['tools']}")
# 十、直接赋值与复制
original_config = {"model": "gpt-5", "enabled": True}
alias_config = original_config
alias_config["model"] = "o3"
print(f"直接赋值后的原字典:{original_config}")
print(f"直接赋值后的别名字典:{alias_config}")
copied_config = original_config.copy()
copied_config["model"] = "gpt-5"
print(f"复制后保持不变的原字典:{original_config}")
print(f"修改后的副本:{copied_config}")

View File

@@ -0,0 +1,105 @@
# 第 1-10 课课堂练习Agent 配置管理器
#
# 完成要求:
# 1. 根据注释完成字典的创建、读取、修改、删除、遍历和嵌套操作。
# 2. 使用有意义的英文蛇形变量名。
# 3. 读取可能不存在的键时使用 get() 或先使用 in 判断。
# 4. 删除键前确认键存在,或为 pop() 提供默认值。
# 5. 不要删除题目注释。
# 6. 完成后运行本文件并核对预期结果。
# 练习一:创建字典 agent_config包含以下键值对
# model"gpt-5"
# temperature0.7
# max_tokens2000
# enabledTrue
# 练习二:输出以下信息:
# 1. 完整字典;
# 2. 键值对数量;
# 3. 使用方括号读取 model
# 4. 使用 get() 读取 temperature。
# 练习三:使用 get() 读取不存在的 timeout并提供默认值 30。
# 将结果保存到 timeout输出该变量。
# 确认执行后 timeout 键仍未自动加入 agent_config。
# 练习四:完成以下添加和修改:
# 1. 添加 timeout值为 60
# 2. 把 temperature 修改为 0.3
# 3. 使用 update() 添加 retries=3并把 max_tokens 修改为 4000。
# 练习五:完成以下成员判断:
# 1. 判断是否存在 model 键,保存到 contains_model
# 2. 判断是否存在 timeout 键,保存到 contains_timeout
# 3. 判断 "gpt-5" 是否直接存在于字典键中,保存到 model_value_is_key。
# 观察第三个结果,理解 in 默认检查键。
# 练习六:使用 pop() 删除 retries。
# 将被删除的值保存到 removed_retries。
# 为 pop() 提供默认值 None避免键不存在时报错。
# 练习七:使用 in 判断 timeout 是否存在。
# 如果存在,使用 del 删除 timeout。
# 练习八:分别完成三种遍历:
# 1. 遍历并输出所有键;
# 2. 遍历并输出所有值;
# 3. 使用 items() 同时遍历键和值格式为“modelgpt-5”。
# 练习九:创建嵌套字典 nested_config
# model 对应一个内部字典,包含 name="gpt-5"、temperature=0.7
# runtime 对应一个内部字典,包含 timeout=30、enabled=True。
# 输出嵌套的模型名称和超时时间。
# 练习十:创建 Agent 列表 agents包含两个字典
# 第一条name="代码助手"、model="gpt-5"、enabled=True
# 第二条name="搜索助手"、model="o3"、enabled=False。
# 使用 for 遍历并输出每个 Agent 的名称、模型和启用状态。
# 练习十一:创建字典 agent_profile
# name="代码助手"
# tools=["搜索", "计算"]。
# 向 tools 列表追加 "写作",再输出工具列表。
# 练习十二:使用 copy() 创建 agent_config 的独立浅复制 backup_config。
# 在 backup_config 中把 model 修改为 "o3"。
# 分别输出两个字典,确认原字典的 model 仍为 "gpt-5"。
# 练习十三:使用 30 个等号输出分隔线,再输出最终报告:
# 1. agent_config
# 2. timeout 的默认读取结果;
# 3. contains_model
# 4. contains_timeout
# 5. model_value_is_key
# 6. removed_retries
# 7. nested_config
# 8. agents
# 9. agent_profile
# 10. backup_config。
# 预期核心结果:
# 初次 get("timeout", 30) 得到 30但不会自动新增键
# 修改后的 temperature 为 0.3
# 修改后的 max_tokens 为 4000
# contains_model = True
# 添加 timeout 后 contains_timeout = True
# model_value_is_key = False
# removed_retries = 3
# timeout 最终被删除;
# 嵌套模型名称为 gpt-5超时时间为 30
# agent_profile 的 tools 包含“写作”;
# backup_config 的模型为 o3但 agent_config 的模型仍为 gpt-5。
# 完成后进行自查:
# 1. 方括号和 get() 是否按要求分别使用;
# 2. get() 默认值是否没有自动写入字典;
# 3. in 是否用于检查键;
# 4. 删除键时是否进行了安全处理;
# 5. items() 是否正确解包为 key 和 value
# 6. 嵌套字典是否使用两层键读取;
# 7. 列表中的每个 Agent 是否使用字典表达;
# 8. 修改 backup_config 是否没有影响 agent_config。

View File

@@ -189,11 +189,11 @@ Python/
## 当前学习进度
- 当前阶段第一阶段——Python 基础语法。
- 当前课程:`1_9_元组`
- 当前状态:第课学习中。
- 已完成课程:`1_1_hello_world``1_8_列表`
- 已创建课程目录:`01_python基础/1_1_hello_world/``01_python基础/1_9_元组/`
- 下一步:阅读第课讲义、运行元组示例并完成课堂练习。
- 当前课程:`1_10_字典`
- 当前状态:第课学习中。
- 已完成课程:`1_1_hello_world``1_9_元组`
- 已创建课程目录:`01_python基础/1_1_hello_world/``01_python基础/1_10_字典/`
- 下一步:阅读第课讲义、运行字典示例并完成课堂练习。
## 建议环境