P2-8.3 字典(dictionary):按键(key)查找值的结构¶
Section ID:
P2-8.3Version:v2026.07.20
在 P2-8.2 中,我们看过了有顺序的值集合,也就是列表(list)。但并不是所有数据都只靠顺序来读取。
在按设置名称查设置值、按标签编号查标签名称、按用户 ID 查用户信息这类场景中,比起位置,更重要的是名字标签。在 Python 中,这种结构通过字典(dictionary)来处理。
这里会说明 字典(dictionary) 与 键(key) 的基本区分。关于 列表(list) 与按顺序访问的代表性说明放在 P2-8.2,关于 值(value) 与 类型(type) 的代表性说明放在 P2-8.1 和 概念词典。这里集中处理的是:应该按什么标准去查找值?
如果前一节里的列表是围绕 它是第几个值? 来读,那么这里的中心就是 它是通过什么名字或标识符来查找? 只要先抓住这个差异,后面即使在同一个循环里同时遍历列表和字典,也更容易区分 到底是按什么标准取出来的?
| 本节要先抓住什么 | 紧接着会出现什么问题 | 之后会在什么地方再次使用 |
|---|---|---|
| 字典是按键查值的结构 | 这会接到 P2-8.4 中“列表和字典如何通过迭代来遍历”。 | 之后在读取配置值、JSON 响应、元数据、评估结果时会反复出现。 |
| 列表与字典的差异,本质上是位置和键的差异 | 这会接到判断“哪种数据更适合哪种结构”的标准。 | 之后会在 DataFrame 列、标签映射、API 响应解释里再次使用。 |
dict[key] 与 get() 在失败处理上不同 | 这会接到“当键可能不存在时,应该怎样处理输入”。 | 之后在预处理、预测结果解析、外部响应检查中都很重要。 |
| 术语 | 本节先要抓住的意思 |
|---|---|
| 字典(dictionary) | 把键和对应值连接起来的映射结构。 |
| 键(key) | 用来查找值的标准名称或标识符。 |
| 值(value) | 与键连接在一起的真实数据。 |
| 映射(mapping) | 把某个标准连接到某个对象上的结构。 |
get() | 在键可能不存在的情况下,让读取方式更安全一点的访问方式。 |
核心判断标准:字典(dictionary):按键(key)查找值的结构¶
- 能把字典(dictionary)解释为键(key)和值(value)的集合。
- 能把字典解释为通用映射(mapping)结构。
- 能把列表与字典的差异解释成位置(index)和键(key)的差异。
- 能说明
dict[key]与dict.get(key)的区别。 - 能读懂配置值、标签映射、样本 ID 查询、列说明等例子。
三个标准¶
这里先看的不是语法,而是 应该按什么标准去查值? 下面三个标准会成为后面阅读迭代和缺失键处理说明时的基础。
| 标准 | 为什么重要 | 本节所需的理解程度 |
|---|---|---|
| 字典是按键查值的结构 | 它能最快帮助你抓住与列表的区别 | 理解这是一个按名字标签或标识符来查找,而不是按位置来查找的结构 |
| 键和值分别是查找标准与被连接的内容 | 它能让配置值、标签映射和 ID 查询都被读成同一种结构 | 能说明成:用 "score" 去找到分数,用 0 去找到标签名称 |
| 初学时先把字典理解成映射会更安全 | 这样不容易一开始就被实现术语 hash map 困住 | 在读代码阶段,先把它看成把键连接到值上的结构 |
字典是按标准查找值的结构¶
一般来说,映射(mapping)就是把某个标准连接到某个值上的结构。这个标准可以叫键(key),而连接到键上的对象可以叫值(value)。
在 Python 中,这种映射结构通常通过字典(dictionary)来表达。
问题场景:我想先看一个最简单的字典例子,通过名字标签来找到值。 输入(input):含有 name、score、passed 这些键的 student 字典。 期望输出(output):会打印 student["name"] 和 student["score"] 的值。 要确认的概念:字典不是按位置,而是按键来查值的映射结构。
如果列表是按位置查值,那么 Python 字典就是按键查值。
| 结构 | 查值的标准 | 例子 |
|---|---|---|
| 列表(list) | 位置(index) | scores[0] |
| 字典(dictionary) | 键(key) | student["score"] |
在 AI 实践里,经常会看到字典。
- 配置值集合:
{"learning_rate": 0.01, "epochs": 10} - 一行数据:
{"text": "hello", "label": "positive"} - API 响应的一部分:
{"model": "example", "tokens": 120} - 模型评估结果:
{"accuracy": 0.91, "loss": 0.32}
当重要的不是“按顺序是第几个值”,而是“它是哪个名字对应的值”时,就使用字典。
| 视角 | 一般说明 | 在 Python 中 |
|---|---|---|
| 映射(mapping) | 把某个标准连接到某个值上的结构 | 使用字典(dictionary) |
| 键(key) | 查找值的标准 | 可以是字符串、数字等可哈希(hashable)的值 |
| 值(value) | 与键连接的对象 | 可以是数字、字符串、列表、字典等多种值 |
字典经常被当作通用 map 结构来使用¶
字典并不只是把多个值集中放在一个地方的语法。Python 官方文档把字典描述为映射类型(mapping type)。所谓映射(mapping),就是把某个键(key)连接到某个值(value)的结构。这个说明不仅适用于 Python,在读取配置文件、JSON 响应、标签映射和元数据时也一样成立。
在这一节里,用下面这个标准来理解字典。
字典就是一种通用 map:给它一个键,就能找到连接着的值。
问题场景:我想看一个最小的对应表,把数字标签改成人能读懂的名字。 输入(input):把 0 和 1 连接到字符串标签上的字典 label_name,以及预测值 1。 期望输出(output):会打印与预测值 1 对应的 "positive"。 要确认的概念:只要给出标准键,字典就能直接取出连接的值。
在这个例子里,如果 prediction 是 1,字典就会找到和键 1 相连的 "positive"。与其像列表那样让人去想“应该查第几个格子”,这里是直接按键取值。
这种感觉在实际工作和 AI 实践中会经常出现。
| 情况 | 按字典来看的方式 |
|---|---|
| 把标签编号改成人能读的名字 | {0: "negative", 1: "positive"} |
| 通过设置名称查设置值 | {"batch_size": 32, "learning_rate": 0.001} |
| 通过用户 ID 查用户信息 | {"u001": {"name": "Kim"}} |
| 通过列名查数据含义 | {"score": "考试分数", "label": "正确标签"} |
字典之所以让人感觉像通用 map,就是因为这些场景:如果键存在,就能马上取出值;如果键不存在,也能确认它不存在。
问题场景:我想确认一种基本模式:只有当设置名称存在于字典中时,才把值取出来。 输入(input):配置字典 config 和待查找的键 learning_rate。 期望输出(output):如果键存在,就会打印对应的设置值。 要确认的概念:字典可以先检查键是否存在,再更安全地取出值。
不过,谈到性能时要小心。字典通常是一种对键查询很有用、很快的结构,但这并不表示它在所有场景里都永远是最优选择。键必须是可哈希(hashable)的,而如果问题本身更重视数据顺序,那么列表或其他结构可能更合适。
字典是 hash map 吗?¶
看到 Python 字典时,自然会冒出一个问题:它是不是 hash map? 简短地回答是:从使用角度看,可以把字典理解成按键查值的映射(mapping)结构;从实现角度看,也可以把它理解成利用哈希(hash)的数据结构。
但在本节中,我们不会马上只把字典叫作 hash map。原因有三点。
第一,Python 官方文档把字典说明为标准映射类型(mapping type)。读者首先需要熟悉的视角是:它把键连接到值上。
第二,hash map 这个词更接近实现方式。它会连带出 hash、hashable、collision、table 这些细节概念。而本节的目的,是在阅读 Python 代码时理解 为什么不是按位置,而是按键查找?,而不是先钻进内部实现。
第三,Python 字典并不能直接等同于 C++ STL 里的某一种命名容器。如果把它理解成像 C++ std::map 那样按键排序的结构,会有偏差;如果把它理解成像 multi-index 那样可以同时用多个索引查询同一份数据的结构,也过头了。Python 官方文档说明,字典键会保留插入顺序(insertion order),但这并不表示它会按键排序。
即便如此,和哈希的联系仍然值得记住。Python 字典的键必须是可哈希(hashable)的。因此,字符串、数字、元组这类不会变化的值经常用作键,而像列表这样可变的值通常不能作为字典键。
问题场景:我想看一个最简单的字典例子:通过字符串键来找分数。 输入(input):scores_by_name,其中名字是键,分数是值。 期望输出(output):会输出和键 "Kim" 对应的分数 82。 要确认的概念:字典查询是通过稳定的键来找到值的动作。
在这个例子里,"Kim" 是键,而 Python 会用这个键去找到连接的值。即使不完全理解内部实现,也要留下这种感觉:如果要按键查值,这个键就必须能稳定地标识它。
| 问题 | 本节中的回答 |
|---|---|
| 字典是 hash map 吗? | 从实现角度可以理解成基于哈希的映射结构。 |
| 那是不是只要记成 hash map 就行? | 初期更安全的做法,是先把它理解成 按键查值的映射。 |
| 它会像 map tree 那样排序吗? | 按官方文档,它保留插入顺序,但不把它解释为按键排序结构。 |
| 它是 multi-index 结构吗? | 不是。一个字典就是通过一个键查一个值的映射。如果需要多个查询标准,就要另外设计结构。 |
| 为什么键会有限制? | 因为键是查值标准,所以必须是可哈希(hashable)的。 |
| 现在需要学习哈希表吗? | 这一节不需要。以后讲数据结构时再深入。 |
还有一点要注意:同一个键不能存多次。如果在同一个键下面存入新值,旧值就会被新值覆盖。
问题场景:我想确认同一个键赋值两次时,最后只会留下最后那个值。 输入(input):空字典 scores,以及对键 "Kim" 的两次赋值。 期望输出(output):字典中 "Kim" 键下面只剩下最后的值 91。 要确认的概念:一个键只指向一个当前值,重新赋值时旧值会被覆盖。
这段代码不会在 "Kim" 这个键下面保存两个分数。只会留下最后的值 91。如果想在一个键下面收集多个值,就必须在值(value)那一侧放入列表。
问题场景:我想看看怎样把一个人的多个分数放在同一个键下面保存。 输入(input):一个字典,其中键 "Kim" 对应分数列表 [82, 91]。 期望输出(output):打印 "Kim" 键下的分数列表。 要确认的概念:如果一个键下需要多个值,就要在值一侧放入像列表这样的集合结构。
因此,Python 字典虽然会给人一种 按键访问很快、很方便 的感觉,但它并不是面向大规模数据的万能索引结构。如果数据非常大、需要同时按多个标准查找,或者排序与范围搜索更重要,就应该考虑数据库、pandas 或其他索引结构。本节只处理这之前的阶段:建立在 Python 代码中最常遇到的那种按键映射感觉。
这里记住下面这些标准。
- 当顺序和位置重要时,使用列表。
- 当按键查值更重要时,使用字典。
- 字典适合用来表示配置值、标签映射、元数据这类“按名字查找的数据”。
- 字典虽然和哈希实现有关,但本节先从映射(mapping)角度来读。
- 不要把字典直接定性成键排序树或 multi-index 结构。
- 像“按键计数”这样边循环边往字典里累积值的模式,会在 P2-8.4 中处理。
使用字典的场景¶
当 按什么标准去查值? 已经很明确时,字典就很合适。
配置值集合¶
问题场景:我想看一个典型的字典用法:通过设置名称查训练配置值。 输入(input):包含 batch_size、learning_rate、epochs 的 config。 期望输出(output):会输出 learning_rate 的值。 要确认的概念:配置数据更重视名字而不是顺序,因此和字典很匹配。
对配置值来说,比起顺序,更重要的是名字。通过 learning_rate 这个名字来查值,比像 config[1] 那样按位置查,意义更清楚。
把标签编号改成人能读的名字¶
问题场景:我想看一个例子,把模型输出的数字标签改成可读的字符串名字。 输入(input):连接数字键和情感名称的 label_map,以及预测标签 2。 期望输出(output):打印字符串 neutral。 要确认的概念:字典经常被当作标签编号和标签名称之间的对照表。
当模型输出是数字标签时,可以使用字典把它转成人类可读的名称。
通过样本 ID 查找数据¶
问题场景:我想看一种结构:通过一个样本 ID,马上找到对应数据的文本。 输入(input):samples_by_id,其中样本 ID 是键,样本信息是值。 期望输出(output):打印 "s001" 对应的文本 "good product"。 要确认的概念:字典可以用作从标识符直达数据正文的查询结构。
当数据变多时,比起“它是第几个数据”,更重要的可能是“它是哪个 ID 的数据”。这时字典就像一张从 ID 通往样本的映射表。
通过列名附加意义¶
问题场景:我想看一个例子:把列名代表什么含义,另外用一张说明表管理起来。 输入(input):column_description,把列名连接到说明字符串上。 期望输出(output):打印键 "score" 的说明。 要确认的概念:字典很适合按名字整理元数据和说明信息。
在读取数据集时,如果把列名的意义另外整理起来,后面的预处理和文档化会轻松很多。
字典看起来像 object,但并不是同一个词¶
由于前面的这些例子,字典看起来可能很像 JSON 中的 object,或者某些语言里的 object 表达。它们都使用花括号,也都按名字来查值。所以在看 API 响应或配置文件时,字典和 object 可能会出现相似的外形。
但在本节中,我们不会把字典叫成 object。因为在 Python 中,object 是一个更大的词。数字、字符串、列表、字典、函数都可以视作 object。而字典只是这些对象之中的一种:它是把键(key)连接到值(value)上的映射(mapping)结构。
| 视角 | Python 字典(dictionary) | 一般 object 视角 |
|---|---|---|
| 核心想法 | 通过键查值的映射(mapping) | 同时拥有状态和行为的对象 |
| 查值标准 | 键(key) | 属性(attribute)、字段(field) |
| AI 实践连接 | 配置值、标签映射、API 响应、元数据 | 类实例、模型对象、库对象 |
| 注意点 | 键不存在时可能报错 | 不同对象的访问方式可能不同 |
因此,把字典先读成“按键查值的结构”,而不是“轻量对象”,误解会更少。至于 object、class、method 这些内容,已经超出本章中心范围,会在以后需要时单独处理。
要小心键可能不存在¶
如果直接从字典里取一个不存在的键,就可能报错。
问题场景:我想展示当直接查一个不存在的键时,会有什么风险。 输入(input):只包含 name 和 score 的字典 student,以及不存在的键 "label"。 期望输出(output):展示查询不存在的键时失败的例子。 要确认的概念:如果默认认为字典里的所有键始终都存在,就可能报错。
因为 "label" 这个键不存在,所以这段代码会失败。
当键可能不存在时,可以使用 get()。
问题场景:我想确认一种更安全一点的方式来读取不存在的键。 输入(input):student.get("label") 和 student.get("label", "unknown")。 期望输出(output):默认会得到 None;如果给定默认值,则会输出 "unknown"。 要确认的概念:当处理键可能缺失的数据时,get() 是一种更安全的查询工具。
当处理数据文件或 API 响应时,如果假定所有键一定都存在,就容易出问题。真实数据里可能会混有缺失值、不同名称的值,或者与预期不同的类型。
用案例来看¶
案例 1. 当你想把标签编号改成人能读的名字时¶
假设一个情感分类模型的预测结果只返回 0、1、2 这样的数字。人看到这些数字,很难立刻理解它们的意义,而在报告或界面上,需要的是 negative、positive、neutral 这种名字。
这时最先想到的方法,也许是把它们按顺序放进列表里。但这里真正重要的并不是“它是第几个值”,而是 哪个编号对应哪个名字。也就是说,比起位置,更重要的是标准键。
字典正是适合读取和书写这种对照表的结构。只要像 0 -> negative、1 -> positive 这样把键和值连接起来,就能很容易把预测数字改成人能读懂的名字。配置值、样本 ID、列说明也都可以用同样方式来看。
可确认的结果,就是把预测标签数字放进去之后,是否能立刻得到名字。如果通过 label_map[prediction] 就能得到想要的字符串,那么这个问题就比起列表,更自然地应该用字典来读。
检查清单¶
- 能把字典(dictionary)解释成键和值的集合。
- 能把字典解释成映射(mapping)结构。
- 能从使用角度把字典解释为映射,从实现角度解释为基于哈希的结构。
- 能说明列表按位置查值,而字典按键查值。
- 能说明
get()在键可能不存在的情况下很有用。 - 能读懂标签映射、配置值、样本 ID 查询、列说明这些例子。
- 能区分在键可能不存在时应该怎样选择读取方式。
来源与参考资料¶
- Python Software Foundation, Data Structures, Python 3.14.6 documentation,确认日期:2026-07-20。用于确认字典创建、通过 key 访问 value,以及使用
items()遍历的示例。 - Python Software Foundation, Mapping Types — dict, Python 3.14.6 documentation,确认日期:2026-07-20。用于确认
dict是 mutable mapping type,并且是通过 key 查找 value 的结构。 - Python Software Foundation, Glossary: dictionary, hashable, Python 3.14.6 documentation,确认日期:2026-07-20。用于确认 dictionary 与 hashable 的术语定义。
- Python Software Foundation, Data model, Python 3.14.6 documentation,确认日期:2026-07-20。用于确认对象的 identity/type/value 和 hashability,作为字典 key 限制的背景依据。