
4.4 字典
在许多应用中需要利用关键词查找对应的信息,例如,通过学号来检索某学生的信息。其中,通过学号查找所对应学生的信息的方式称为“映射”。Python语言的字典(Dictionary)类型就是一种映射。其他编程语言中也提供类似的结构,例如,哈希(Hash)、关联数组等。
字典(Dictionary)和列表类似,也是可变序列,不过与列表不同,它是无序的可变序列,保存的内容是以“键值对”的形式存放的。这类似于《新华字典》,它可以把拼音和汉字关联起来。通过音节表可以快速找到想要的汉字。其中,《新华字典》里的音节表相当于键(Key),而对应的汉字相当于值(Value)。键是唯一的,而值可以有多个。
字典的主要特征如下。
1.通过键而不是通过索引来读取
字典有时也称为关联数组或者散列表(Hash)。它是通过键将一系列的值联系起来的,这样就可以通过键从字典中获取指定项,但不能通过索引来获取。
2.字典是任意对象的无序集合
字典是无序的,各项是从左到右随机排序的,即保存在字典中的项没有特定的顺序。这样可以提高查找效率。
3.字典是可变的,并且可以任意嵌套
字典可以在原处增长或者缩短(无须生成一份拷贝),并且它支持任意深度的嵌套(即它的值可以是列表或者其他的字典)。
4.字典中的键必须唯一
不允许同一个键出现两次,如果出现两次,则后一个值会被记住。
5.字典中的键必须不可变
字典中的键是不可变的,所以字典中的键可以使用数字、字符串或者元组,但不能使用列表。
4.4.1 字典的创建
字典包含了一个索引的集合,称为键(Key)和值(Value)的集合。一个键对应一个值。这种一一对应的关联称为键值对(Key-Value Pair),或称为项(Item)。简单地说,字典就是用花括号包裹的键值对的集合。每个键值对用冒号“:”分隔,每对之间用逗号“,”分隔,语法格式如下。

参数说明:
● key1,key2,...,keyn:表示元素的键,必须是唯一的,并且不可变,例如可以是字符串、数字或者元组。
● valuel,value2,...,valuen:表示元素的值,可以是任何数据类型,不是必须唯一。
【例4-38】 新建并显示字典。

运行结果:

同列表和元组一样,也可以创建空字典。在Python中,可以使用下面两种方法创建空字典。

或者

Python的dict()方法除了可以创建一个空字典外,还可以通过已有数据快速创建字典。主要表现为以下两种形式。
1.通过映像函数创建字典
语法格式为:dictionary=dict(zip(list1,list2))
参数说明:
● dictionary:表示字典名称。
● zip函数:用于将多个列表或元组对应位置的元素组合为元组,并返回包含这些内容的zip对象。如果想得到元组,可以将zip对象使用tuple函数转换为元组;如果想得到列表,则可以使用list函数将其转换为列表。
● list1:表示一个列表,用于指定要生成字典的键。
● list2:表示一个列表,用于指定要生成字典的值。如果list1和list2的长度不同,则与最短的列表长度相同。
【例4-39】 定义两个各包括4个元素的列表,再应用dict函数和zip函数将前两个列表转换为对应的字典,并输出该字典。

运行结果:

2.通过给定的“键值对”创建字典
语法格式如下。

参数说明:
● dictionary:表示字典名称。
● keyl,key2,...,keyn:表示元素的键,必须是唯一的,并且不可变,例如可以是字符串、数字或者元组。
● valuel,value2,...,valuen:表示元素的值,可以是任何数据类型,不是必须唯一。
【例4-40】 应用“键值对”创建字典。

运行结果:

在Python中,还可以使用dict对象的fromkeys()方法创建值为空的字典,语法如下:dictionary=dict.fromkeys(list1)
参数说明:
● dictionary:表示字典名称。
● list1:作为字典的键的列表。
4.4.2 字典元素的访问与遍历
1.字典元素的访问
在Python中,如果想将字典的内容输出也比较简单,可以直接使用print函数。比如print(dictname)。但是,在使用字典时,很少直接输出它的内容。一般需要根据指定的键得到相应的结果。
在Python中,访问字典的元素可以通过下标的方式实现,与列表和元组不同,这里的下标不是索引号,而是键。
在实际开发中,很可能不知道当前存在什么键,所以需要避免该异常的产生。具体的解决方法是使用if语句对不存在的情况进行处理,即给一个默认值。
【例4-41】 字典元素的访问。

运行结果:中国农业大学
Python中推荐的方法是使用字典对象的get()方法获取指定键的值。
其语法格式如下。

其中,dictname为字典对象,即要从中获取值的字典;key为指定的键;default为可选项,用于当指定的键不存在时,返回一个默认值,如果省略,则返回None。
为了解决在获取指定键的值时,因不存在该键而导致抛出异常,可以为get()方法设置默认值,这样当指定的键不存在时,得到结果就是指定的默认值。
【例4-42】 使用get()方法访问字典元素。

运行结果:中国农业大学
2.字典元素的遍历
字典是以“键值对”的形式存储数据的,所以就可能需要对这些“键值对”进行获取。Python提供了遍历字典的方法,通过遍历可以获取字典中的全部“键值对”。
使用字典对象的items()方法可以获取字典的“键值对”列表。
其语法格式如下。

其中,dictionary为字典对象;返回值为可遍历的“键值对”元组列表。想要获取到具体的“键值对”,可以通过for循环遍历该元组列表。
【例4-43】 定义一个字典,然后通过items()方法获取“键值对”的元组列表,并输出全部“键值对”“键”“值”。

运行结果:

在Python中,字典对象还提供了values()方法和keys()方法,用于返回字典的值和键列表,它们的使用方法同items()方法类似,也需要通过for循环遍历该字典列表,获取对应的值和键。
4.4.3 字典元素的常见操作(增、删、改、查)
1.字典元素的增加
由于字典是可变序列,所以可以随时在其中增加“键值对”,这和列表类似。向字典中添加元素的语法格式如下。

参数说明:
● dictionary:表示字典名称。
● key:表示要增加元素的键,必须是唯一的,并且不可变,例如可以是字符串、数字或者元组。
● value:表示元素的值,可以是任何数据类型,不是必须唯一。
【例4-44】 增加并显示字典元素。
dictname={'pku':'北京大学','tsinghua':'清华大学','fudan':'复旦大学'}dictname['sju']='上海交通大学'print(dictname)
运行结果:

注:如果key存在则修改这个key对应的值;如果key不存在则新增此键值对。
2.字典元素的删除
同列表和元组一样,不再需要的字典也可以使用del命令删除。另外,如果只是想删除字典的全部元素,可以使用字典对象的clear()方法。执行clear()方法后,原字典将变为空字典。由于当删除一个不存在的键时,将抛出异常,所以可以先判断此元素是否存在,然后再删除。
(1)del:删除字典或删除字典中指定键值对
【例4-45】 字典元素的删除示例。

运行结果:

(2)clear():清空字典
【例4-46】 字典元素的清空示例。

运行结果:

(3)pop():获取指定key对应的value,并删除这个键值对
【例4-47】 pop()方法的用法。

运行结果:

3.字典元素的修改
由于在字典中,“键”必须是唯一的,所以如果新添加元素的“键”与己经存在的“键”重复,那么将使用新的“值”替换原来该“键”的值,这也相当于修改字典的元素。
【例4-48】 字典元素的修改。


运行结果:

4.字典元素的查找
如果当前查找的“键”存在,则返回对应的值;否则会报错。可以通过如下两种方式查找字典元素。
1)通过键值方式。前边已经讲述过。
2)通过get()、keys()、values()以及items函数方式查找。
【例4-49】 字典元素的查找示例。

运行结果:

字典值可以没有限制地取任何Python对象,既可以是标准的对象,也可以是用户定义的对象,但键不行。
注意:
1)不允许同一个键出现两次。创建时如果同一个键被赋值两次,则后一个值会被记住。
2)键必须不可变,可以用字符串或元组充当,而列表就不能作为键。