当前位置:首页>python>第2.6章:快速学习Python的字典与集合

第2.6章:快速学习Python的字典与集合

  • 2026-10-11 06:12:04
第2.6章:快速学习Python的字典与集合

《Python AI 应用开发入门》第 2.6 节。

使用字典表示结构化聊天消息,使用集合完成去重和集合运算。

本节目标

学完本节后,你应当能够:

  1. 1. 创建字典并完成字段的增、删、改、查。
  2. 2. 区分方括号访问与 get()。
  3. 3. 使用嵌套字典和列表表示聊天消息。
  4. 4. 使用集合完成去重、成员判断和集合运算。
  5. 5. 根据“按名称查找”或“保留唯一值”的需求选择容器。

1. 为什么需要字典

列表可以保存一条消息:

message = ["user", "请解释字典", 1]

但只看值很难知道每个位置的含义。字典使用键给数据命名:

message = {
    "role"
: "user",
    "content"
: "请解释字典",
    "sequence"
: 1,
}

字典保存键和值的映射。上例中:

  • • "role" 是键,"user" 是值。
  • • "content" 是键,问题文本是值。
  • • "sequence" 是键,1 是值。

键必须唯一;重复键只会保留后面的值。

2. 创建和读取字典

message = {
    "role"
: "user",
    "content"
: "请解释字典",
    "sequence"
: 1,
}

print
(message["role"])
print
(message["content"])
print
(len(message))

len() 返回键值对数量。

访问不存在的键会触发 KeyError:

# print(message["model"])

如果字段可能不存在,可以使用 get():

print(message.get("model"))
print
(message.get("model", "尚未选择"))

找不到时,get() 默认返回 None,也可以提供默认值。

原则:

  • • 必填字段缺失应该暴露问题时,用方括号。
  • • 可选字段允许不存在时,用 get()。

3. 新增和修改

语法相同:

message["model"] = "demo-mini"       # 新增
message["content"] = "请举例解释字典"  # 修改

使用 update() 一次更新多个字段:

message.update({
    "model"
: "demo-pro",
    "status"
: "completed",
})

如果键已存在就更新,不存在就新增。

4. 删除字段

message = {
    "role"
: "user",
    "content"
: "你好",
    "temporary"
: True,
}

removed_value = message.pop("temporary")
print
(removed_value)

键不存在时 pop() 会触发 KeyError,可以提供默认值:

removed_value = message.pop("missing", None)

清空全部字段:

message.clear()

5. 检查键和值

in 默认检查键:

message = {"role": "user", "content": "你好"}

print
("role" in message)             # True
print
("user" in message)             # False
print
("user" in message.values())    # True

常见视图:

print(message.keys())
print
(message.values())
print
(message.items())

items() 中每一项是 (键, 值) 元组。下一节会使用循环逐项处理:

for key, value in message.items():
    print
(f"{key}: {value}")

这里先理解输出结构;循环语法会在第 2.7 节完整学习。

6. 嵌套数据

聊天历史通常是“列表中保存多个字典”:

messages = [
    {
        "role"
: "user",
        "content"
: "什么是列表?",
    },
    {
        "role"
: "assistant",
        "content"
: "列表是有顺序的可变容器。",
    },
]

读取第一条消息的内容:

print(messages[0]["content"])

读取最后一条消息的角色:

print(messages[-1]["role"])

新增一条消息:

new_message = {
    "role"
: "user",
    "content"
: "列表与元组有什么区别?",
}
messages.append(new_message)

这种结构与 Web API 中常见的 JSON 数据很接近。第 3 章会学习 JSON 文件读写。

7. 字典也是可变的

message = {"role": "user", "content": "你好"}
same_message = message
same_message["content"] = "已修改"

print
(message["content"])

结果是“已修改”。两个变量指向同一字典。

需要复制这一层时:

message_copy = message.copy()

和列表一样,嵌套结构的浅复制不会自动复制内部的所有对象。

8. 什么是集合

集合是一组不重复、没有位置索引的值:

keywords = {"Python", "AI", "字典"}

集合适合:

  • • 去除重复值。
  • • 快速判断成员是否存在。
  • • 比较两组标签的共同项和差异。

创建空集合必须写:

keywords = set()

{} 创建的是空字典,不是空集合:

print(type({}))
print
(type(set()))

9. 集合的增删与成员判断

keywords = {"Python", "AI"}

keywords.add("字典")
keywords.add("Python")
print
(keywords)

重复添加 "Python" 不会产生第二份。

删除:

keywords.remove("AI")
keywords.discard("不存在的词")

remove() 找不到时触发 KeyError;discard() 找不到时不会报错。

成员判断:

print("Python" in keywords)

集合输出顺序不应被依赖。需要固定顺序显示时可以先排序:

print(sorted(keywords))

10. 用集合去重

tags = ["Python", "AI", "Python", "入门", "AI"]
unique_tags = set(tags)

print
(unique_tags)
print
(len(unique_tags))

这种方式不保证保留原顺序。如果需要按首次出现顺序去重,后续可以使用循环逐项处理。

文本关键词还需要先标准化,否则大小写不同会被视为不同值:

raw_tags = ["Python", "python", " PYTHON "]
normalized_tags = {
    raw_tags[0].strip().lower(),
    raw_tags[1].strip().lower(),
    raw_tags[2].strip().lower(),
}

print
(normalized_tags)

11. 集合运算

user_interests = {"Python", "RAG", "FastAPI"}
course_tags = {"Python", "AI", "FastAPI"}

交集:两边都有

print(user_interests & course_tags)

并集:合并全部唯一值

print(user_interests | course_tags)

差集:左边有、右边没有

print(user_interests - course_tags)

对称差集:只在一边出现

print(user_interests ^ course_tags)

这些运算很适合标签匹配、权限比较和关键词分析。

12. 四种容器如何选择

需求
容器
按顺序保存、会增删的聊天记录
列表
保存固定的有序配置
元组
用字段名表示一条消息
字典
保存不重复关键词、做集合比较
集合

真实数据经常组合使用:

chat = {
    "title"
: "Python 学习",
    "participants"
: ("user", "assistant"),
    "tags"
: {"Python", "基础"},
    "messages"
: [
        {"role": "user", "content": "你好"},
        {"role": "assistant", "content": "你好!"},
    ],
}

选择容器时先问:

  1. 1. 是否需要顺序?
  2. 2. 是否需要按名称查找?
  3. 3. 是否允许重复?
  4. 4. 是否需要修改?

动手练习

练习 1:结构化消息

创建 message_record.py:

  1. 1. 使用字典保存角色、内容、模型和是否完成。
  2. 2. 输出角色和内容。
  3. 3. 修改完成状态。
  4. 4. 使用 get() 读取可选的 error 字段,默认显示“无错误”。

练习 2:聊天历史

创建一个包含三条消息的列表,每条消息都是字典。输出:

  • • 消息总数。
  • • 第一条消息的内容。
  • • 最后一条消息的角色。

再追加一条新消息并更新总数。

练习 3:关键词集合

给定两组关键词:

question_tags = {"Python", "列表", "入门"}
course_tags = {"Python", "字典", "入门"}

输出共同关键词、全部关键词和只在问题中的关键词。

随堂小测

  1. 1. 字典中的键为什么不能重复?
  2. 2. message["model"] 与 message.get("model") 在键不存在时有什么区别?
  3. 3. in 直接用于字典时检查键还是值?
  4. 4. 为什么聊天历史常用“列表中保存字典”?
  5. 5. {} 与 set() 分别创建什么?
  6. 6. remove() 和 discard() 删除不存在的集合元素时有什么区别?
  7. 7. 哪个集合运算能找到两组标签的共同项?

参考答案

  1. 1. 键用于唯一定位对应的值;重复键无法同时表示两个映射,后面的值会覆盖前面的值。
  2. 2. 方括号触发 KeyError;get() 返回 None 或指定默认值。
  3. 3. 键。
  4. 4. 列表保留多条消息的顺序,字典用字段名清楚表示每条消息的结构。
  5. 5. {} 创建空字典,set() 创建空集合。
  6. 6. remove() 触发 KeyError,discard() 不报错。
  7. 7. 交集 &。

本节完成检查

  • • 我能完成字典的增、删、改、查。
  • • 我知道何时使用方括号或 get()。
  • • 我能读写列表中的消息字典。
  • • 我能创建空集合并完成去重。
  • • 我会使用交集、并集和差集。
  • • 我完成了三个动手练习。

最新文章

随机文章