
3.2.3 Python的字典
字典是Python中的一种具有映射性质的数据类型,即由“键-值”(key-value)两部分构成,组成键-值对。早期,在C/C++中并没有这样的类型(直到C++有了STL,其中提供了map方法,不过Python的字典较C++的map更为实用、方便),只能使用哈希算法。“哈希”对应英文单词hash,意思为“散列”。
使用哈希算法可以避免遍历整个数组,同时可以计算输入的整数出现的次数。这样大大降低了复杂度。这个算法的含义是:当读入的数为x时,就令hashTable[x]=true(说明hashTable数组需要被初始化为false,表示初始状态下所有数都未出现过)。
“哈希”也分为键和值,在hashTable[x]=true中,x就是这个哈希的“键”(key),而布尔值true则是哈希的“值”(value),而Python的“字典”类型普遍被当作一种可变的哈希表来使用。字典不同于列表和元组,列表和元组是有序的,即序号值(index)从0~n-1有序排列;而字典是无序的,字典的键(key)可以是字符串,也可以是数字,它们之间不需要有任何联系,所以字典的键(key)完全是无序的。
前面提到,字典具有映射性质,“映射”是初等数学中常见的一个概念,即可以表达一种相对应的关系,可以是一对一、一对多,还可以是多对多。例如,一元一次函数是一条直线,所以x与y是一对一的关系;而一元二次函数是抛物线,是一对二(多)的关系;椭圆曲线不是“函数”,因为函数关系只能是一对多的,椭圆曲线是二对二(即多对多的范畴)的关系。下面来举一个例子,创建字典并对它赋值,可以直接给出键-值对,也可以使用内建方法fromkeys()和dict()来创建字典。


输出结果:

那么如何通过遍历来读取字典里“键-值对”的“值”呢?一般查看“键-值对”的值都是通过键来实现的,所以可以通过遍历字典的键来取出它的值。当然,Python3支持直接遍历字典本身(实际上是用宏省去了键,本质并没有变),也可以通过某个键得到字典的值,示例如下:

输出结果:

由此可见,Python的字典是C/C++的哈希算法的极佳“替代品”,省去了程序员自己写算法的步骤,方便易用。当然,在使用第三种方法(直接通过字典的键来得到值)时,如果输错了“键”或者这个“键”根本不存在,就得不到正确的结果。过去可以用has_key()方法来判断某个键是否存在于某个字典中,但是has_key()方法已经被淘汰,有了更方便的方法,那就是in和not in,示例如下:

输出结果:

字典不是元组,它支持通过“=”赋值符号更新字典的值,并且也支持用户使用del语句手动回收字典及其占用的内存空间。下面介绍Python对于字典类型定义的内建函数,内建函数有3个(第4个内建函数cmp在Python3中已被淘汰),分别为len()、str()、type(),如表3-5所示。
表3-5 Python字典的内建函数

表3-5中的3个内建函数的示例如下:

输出结果:

type()是一个常见的内建函数,基本所有类型的内建函数都有它的定义。当然,Python的字典还有其他内建函数,如表3-6所示。
表3-6 Python字典的其他内建函数

续表
