int,整数类型(整形)
float,浮点类型(浮点型)
complex,复数类型
bool,布尔类型
str,字符串类型
高级数据类型
list,列表类型
tuple,元组类型
set,集合类型
dict,字典类型
学习目标:
掌握字典相关知识。
迄今为止,我们已经为大家介绍了Python中的三种容器型数据类型,但是这些数据类型还不足以帮助我们解决所有的问题。例如,我们要保存一个人的信息,包括姓名、年龄、体重、单位地址、家庭住址、本人手机号、紧急联系人手机号等信息,你会发现我们之前学过的列表、元组和集合都不是最理想的选择。
1 | person1 = ['王小二', 22, 60, '榆次区新建北路1258号', '河北石家庄', '139354028795', '13800998877'] |
集合肯定是最不合适的,因为集合有去重特性,如果一个人的年龄和体重相同,那么集合中就会少一项信息;同理,如果这个人的家庭住址和单位地址是相同的,那么集合中又会少一项信息。另一方面,虽然列表和元组可以把一个人的所有信息都保存下来,但是当你想要获取这个人的手机号时,你得先知道他的手机号是列表或元组中的第6个还是第7个元素;当你想获取一个人的家庭住址时,你还得知道家庭住址是列表或元组中的第几项。总之,在遇到上述的场景时,列表、元组、字典都不是最合适的选择,我们还需字典(dictionary)类型,这种数据类型最适合把相关联的信息组装到一起,并且可以帮助我们解决程序中为真实事物建模的问题。
说到字典这个词,大家一定不陌生,读小学的时候每个人基本上都有一本《新华字典》,如下图所示。

Python程序中的字典跟现实生活中的字典很像,它以键值对(键和值的组合)的方式把数据组织到一起,我们可以通过键找到与之对应的值并进行操作。就像《新华字典》中,每个字(键)都有与它对应的解释(值)一样,每个字和它的解释合在一起就是字典中的一个条目,而字典中通常包含了很多个这样的条目。
一、字典的定义
通过对比列表、元组和集合,我们来看一下字典的定义:
列表(list),是一个有序且可变的容器,在里面可以存放多个不同类型、数据元素可重复的元素。
元组(tuple),是一个有序且不可变的容器,在里面可以存放多个不同类型、数据元素可重复的元素。
集合(set),是一个 无序 且可变的容器,在里面可以存放多个不同类型、数据元素不可重复的元素。
字典(dict),是一个 有序、可变、元素只能是键值对的容器,在里面可以存放多个不同类型、键不可重复的元素。
字典的特点
- 元素必须键值对
- 键不重复,重复则会被覆盖
- 有序(在Python3.6+字典就是有序了,之前的字典都是无序)
- 数据元素可以改变
字典中对键值的要求:
- 键:必须可哈希。 目前为止学到的可哈希的类型:int/bool/str/tuple;不可哈希的类型:list/set/dict。
- 值:任意类型。
注意点
- 字典的键和集合的元素在遇到 布尔值 和 1、0 时,需注意重复的情况。
二、字典的创建
在Python中创建字典可以使用{}
字面量语法,这一点跟上一节讲的集合是一样的。但是字典的{}
中的元素是以键值对的形式存在的,每个元素由:
分隔的两个值构成,:
前面是键,:
后面是值,代码如下所示。
1 | xinhua = { |
通过上面的代码,相信大家已经看出来了,用字典来保存一个人的信息远远优于使用列表或元组,因为我们可以用:
前面的键来表示条目的含义,而:
后面就是这个条目所对应的值。
当然,如果愿意,我们也可以使用内置函数dict
或者是字典的生成式语法来创建字典,代码如下所示。
1 | # 创建空字典 |
想知道字典中一共有多少组键值对,仍然是使用len
函数;如果想对字典进行遍历,可以用for
循环,但是需要注意,for
循环只是对字典的键进行了遍历,不过没关系,在讲完字典的运算后,我们可以通过字典的键获取到和这个键对应的值。
1 | person = { 'name': '王小二', 'age': 22, 'weight': 60, 'office': '榆次区新建北路1258号'} |
三、字典的方法
字典类型的方法基本上都跟字典的键值对操作相关,字典中常见的方法如下:
- 添加
- setdefault(key, value):无此键则添加,有此键则不变
- dict[key] = value:无此键则添加,有此键则更新
- 删除
- pop(key):删除指定键对应的键值对,返回key对应的值
- popitem(),按顺序删除一个键值对,先进先出,返回这个键值对对应的二元组(key, value)
- del dict[key]:删除指定键对应的键值对,无返回值
- 更新
- dict[key] = value:若key存在则修改为value
- update(dict2):将dic2中的所有键值对覆盖添加(相同的键覆盖,不同的键值对添加)到dic中,dic2不变
- 查询
- get(key, default=None):如果指定的键key存在,则返回对应的值,否则返回default,default默认为空。
- keys():获取字典所有的键,返回的是
高仿列表
,这个高仿的列表可以被循环显示,不能通过下标取值。 - values():获取字典所有的值,返回的是
高仿列表
,这个高仿的列表可以被循环显示, 不能通过下标取值。 - items():获取字典所有的键值对,返回的是
高仿列表
,列表中的元素为(key, value)形式的二元组,这个高仿的列表可以被循环显示,不能通过下标取值。
- 清空
- clear(),清空字典
可以通过下面的例子来了解这些方法的使用。例如,我们要用一个字典来保存学生的信息,我们可以使用学生的学号作为字典中的键,通过学号做索引运算就可以得到对应的学生;我们可以把字典中键对应的值也做成一个字典,这样就可以用多组键值对分别存储学生的姓名、性别、年龄、籍贯等信息,代码如下所示。
1 | # 字典中的值又是一个字典(嵌套的字典) |
跟列表一样,从字典中删除元素也可以使用del
关键字,在删除元素的时候如果指定的键索引不到对应的值,一样会引发KeyError
异常,具体的做法如下所示。
1 | person = {'name': '王大锤', 'age': 25, 'sex': True} |
四、字典的运算
对于字典类型来说,和集合类似,支持成员运算、索引运算,前者可以判定指定的键在不在字典中,后者可以通过键获取对应的值或者向字典中加入新的键值对。除此之外,python3.9还引入了并集运算。值得注意的是,字典的索引不同于列表的索引,列表中的元素因为有属于自己有序号,所以列表的索引是一个整数;字典中因为保存的是键值对,所以字典的索引是键值对中的键,通过索引操作可以修改原来的值或者向字典中存入新的键值对。需要特别提醒大家注意的是,字典中的键必须是不可变类型,例如整数(int
)、浮点数(float
)、字符串(str
)、元组(tuple
)等类型的值;显然,列表(list
)和集合(set
)是不能作为字典中的键的,当然字典类型本身也不能再作为字典中的键,因为字典也是可变类型,但是字典可以作为字典中的值。关于可变类型不能作为字典中的键的原因,我们在后面的课程中再为大家详细说明。这里,我们先看看下面的代码,了解一下字典的常见运算。
字典的常见运算如下:
- 成员运算
- in:判断指定键是否在字典中存在,若存在返回True,否则返回False
- not in:判断指定键是否在字典中存在,若存在返回True,否则返回False
- 索引运算
- dict[key]:获取指定key对应的value,和字典的get方法不同的是,若key不存在,会引发KeyError异常
- dict[key] = value:若key存在,则将key对应的值更新为value,否则添加键值对key和value
- 长度
- len():获取字典中元素的个数
- 并集
- 字典A
|
字典B:返回两个字典的并集,结果中包含A和B所有的键,若字典A中不存在则添加,若存在则更新。
- 字典A
使用示例如下:
1 | person = {'name': '张三', 'age': 18, 'weight': 60, 'office': '榆次区新建北路98号'} |
需要注意,在通过索引运算获取字典中的值时,如指定的键没有在字典中,将会引发KeyError
异常。
五、字典的循环遍历
由于字典也属于是容器,内部可以包含多个键值对,可以通过循环对其中的:键、值、键值进行循环;
1 | # 默认循环key |
六、字典的类型转换
只有列表里面嵌套二元组的数据格式可以转化为字典,语法为:dict(data)
,字典转列表有三种:key转列表,value转列表,key和value同时转列表,格式为[(key,value),...]
这样的格式。
1 | # 列表转字典,列表元素必须为二元组 |
我们已学了很多数据类型,在涉及多种数据类型之间的嵌套时,需注意一下几点:
字典的键必须可哈希(list/set/dict不可哈希)。
字典的值可以是任意类型。
字典的键和集合的元素在遇到 布尔值 和 1、0 时,需注意重复的情况。
七、字典生成式
1 | d = {key : value for (key,value) in iterable} 其中iterable是一个可迭代的对象,比如list。 |
示例1: for 循环遍历列表,将列表中小元组的key和value取出,作为字典中的key:value
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import random
students = {}
for i in range(20):
name = f'stu{i}'
score = random.randint(60, 100)
students[name] = score
print(students)
highscore = {}
for name. score in students.items():
if score > 90:
highscore[name] = score
print(highscore)
print({name: score for name, score in students.items() if score > 90})示例2:字典的key和value值互换
1
2
3dict1 = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
dict2 = {v: k for k, v in dict1.items()}
print(dict2) # {1: 'a', 2: 'b', 3: 'c', 4: 'd'}
八、知识扩展
1. 字典合并的几种方式
1 | d1 = {'name': 'Tom', 'age': 20} |
方式一
1
2
3
4
5
6dnew = dict()
for key, value in d1.items():
dnew[key] = value
for key, value in d2.items():
dnew[key] = value
# dnew == {'name': 'Tom', 'age': 20, 'gpa': 4.0, 'is_single': True}方式二
1
2dnew = d1.copy()
dnew.update(d2)方式三
1
dnew = {**d1, **d2}
方式四
1
dnew = dict(d1, **d2)
方式五
1
2dnew = d1 | d2
# dnew == {'name': 'Tom', 'age': 20, 'gpa': 4.0, 'is_single': True}这种联合运算符实际上在Python中不是新的, 它可以用于“合并”两个集合, 集合是无序且没有索引的集合,要用花括号括起来。
1
2
3
4a = {1, 2, 3}
b = {3, 4, 5}
print( a | b )
# {1, 2, 3, 4, 5}
2. 默认字典
Python中通过Key访问字典,当Key不存在时,会引发‘KeyError’异常。为了避免这种情况的发生,可以使用collections类中的defaultdict()方法来为字典提供默认值.
示例1:字符计数
1 | from collections import defaultdict |
可用dict.setdefault()
改进
1 | from collections import defaultdict |
进一步用默认字典collections.defaultdict
改进,自动设置键和值
1 | from collections import defaultdict |
示例2:分类
1 | from collections import defaultdict |
示例3:构建set集合
1 | from collections import defaultdict |
3. 字典排序
3.1 按key排序
1 | dict1 = {'b': 2, 'd': 4, 'a': 1, 'c': 3} |
3.2 按value排序
1 | dict1 = {'b': 2, 'd': 4, 'a': 1, 'c': 3} |
3.3 字典列表排序
1 | lis = [{ "name" : "Taobao", "age" : 100}, |
九、简单的总结
Python程序中的字典跟现实生活中字典非常像,允许我们以键值对的形式保存数据,再通过键索引对应的值。这是一种非常有利于数据检索的数据类型,底层原理我们在后续的课程中再研究。