学径 LearnPath

编程语言基础 / Wiki

字典

用键而不是位置去取对应的值;适合「记得名字、而不是记得排第几」的查找。

它是什么

字典 存放「键到值」的对应。查的时候不靠第几格,而靠名字。适合「按学号找成绩」「按城市名找人口」这类问题:记得的是那个键,不是它排在第几。键必须是不可变的:字符串、数字、内部也不可变的 元组 可以;列表 不可以。

python
scores = {"语文": 90, "数学": 88}
print(scores["数学"])
scores["英语"] = 85

花括号里是成对的项,中间用冒号连起来。键是唯一的:后写的会盖掉先写的。同一键出现两次、表示两个值,并不在这份结构的模型里。

名字从哪来

dictionary 就是词典:左边词条,右边解释。计算机科学里常叫映射、关联数组或哈希表——内部用散列方法,让按键查找平均很快。Python 对外就叫 dict,并保证在现代版本里按插入顺序排列。顺序在这里是遍历时的便利,不是「第 0 个元素」那种稳定的位置语义。不要用整数下标去假装它是列表。

散列要求键可哈希,因此可变对象不能当键。需要复合键时,改用元组。这不是挑剔,而是在保证:作为查找依据的那一份标识,自身不会在中途被改掉。

它怎么工作

d[key] 取值,键不存在会引发 KeyError。更稳妥的是先判断 key in d,或用 d.get(key)。None 是调用 get 时可以设定的缺省,不是方括号取缺失键时的默认结果。赋值给一个新键,就是新增;赋给旧键,就是覆盖。

for key in d 默认遍历键。需要值和键一起时,用 d.items()。值为可变对象时,改的是那个对象,字典里对应的键仍然指向它。两个列表平行地一个装名字一个装分数,能凑合用,但容易对错位;字典把一对锁在一起。

生活里在哪里

纸质词典、通讯录按名字查号码;座位表按学号找位置,而不是从第一张桌子数起;菜单上菜名对应价格。目录、索引、户籍册,都是「不靠排队次序、靠标识去取」的社会技术。当问题的核心是查找而不是遍历次序,字典比列表更接近问题本身。把本该用键的模型写成两个易错位的列表,程序可以能跑,却在对世界的描述上松了扣。见 对话式编程。

和相近概念的差别

列表用位置。集合 只有键、没有对应的值,用来判断「有没有出现过」。字典两者都要:既有键,也有值。空的 {} 是空字典,不是空集合;空集合要写 set()。

类也可以把数据挂在对象上,并配上方法。字典更轻,适合「一份对应关系算完就结束」;当操作开始变多、状态需要长期存在,类 比一堆字典更不容易散。

常见误会

误会 1:键不存在时会得到 None。

直接用方括号会报错。None 是你自己用 get 时可以设定的缺省。

误会 2:同一个键可以出现两次、表示两个值。

键是唯一的。后写的会盖掉先写的。

误会 3:用列表当键,图个方便。

列表可变,不能当键。需要复合键时,改用元组。

想知道更多

  • 书:布鲁克希尔《计算机科学概论》
  • 书:埃里克·马瑟斯《Python编程:从入门到实践(第3版)》
  • 书:艾伦·唐尼《像计算机科学家一样思考Python(第2版)》

未登录时不会保存学习进度