Files

第 1-10 课:字典

一、本课目标

完成本课后,你应该能够:

  1. 解释键值对是什么;
  2. 创建字典和空字典;
  3. 使用键读取字典中的值;
  4. 使用 get() 安全读取数据;
  5. 添加和修改键值对;
  6. 使用 pop()delclear() 删除数据;
  7. 使用 keys()values()items()
  8. 遍历字典的键、值和键值对;
  9. 使用嵌套字典表达分组配置;
  10. 使用列表保存多个字典记录;
  11. 理解字典键的基本限制;
  12. 判断列表、元组和字典的适用场景。

二、前置知识

开始本课前,你应该已经掌握:

  • 字符串、数字和布尔值;
  • 列表与元组;
  • 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() 每次提供一个包含键和值的二元素元组,再通过元组解包分别交给 keyvalue

十四、字典是否有顺序

现代 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 列表。

二十五、思考题

  1. 字典与元组相比,读取配置时有什么优势?
  2. 方括号读取与 get() 有什么区别?
  3. in 默认判断字典的键还是值?
  4. 为什么字典键必须唯一?
  5. 为什么列表不能作为字典键?
  6. items() 遍历时为什么可以使用两个变量?
  7. 列表中保存字典适合表达什么数据?

二十六、本课小结

  • 字典使用键值对保存数据;
  • 键用于定位数据,值是真正保存的内容;
  • 方括号适合读取必须存在的键;
  • get() 可以安全读取并提供默认值;
  • 字典是可变对象,可以增删改键值对;
  • keys()values()items() 提供不同遍历方式;
  • 键必须唯一且可哈希;
  • 字典可以嵌套,也可以与列表组合;
  • 字段明确的数据通常适合使用字典。

二十七、验收标准

  • 能创建字典和空字典;
  • 能使用方括号和 get() 读取值;
  • 能安全添加、修改和删除键值对;
  • 能判断键是否存在;
  • 能遍历键、值和键值对;
  • 能使用嵌套字典;
  • 能使用列表保存多个字典;
  • 能解释常见字典键限制;
  • 能完成并运行 practice.py
  • 能回答七道思考题。