好好学Python:从零基础到项目实战
上QQ阅读APP看书,第一时间看更新

5.2 创建和使用字典

在Python中,创建字典的语法格式如下:

>>> d = {key1 : value1, key2 : value2 }

字典由多个键及其对应的值构成的键值对组成(一般把一个键值对称为一个项)。字典的每个键值对(key/value)用冒号(:)分隔,每个项之间用逗号(,)分隔,整个字典包括在花括号({})中。空字典(不包括任何项)由两个花括号组成,如{}。

在定义的一个字典中,键必须是唯一的,一个字典中不能出现两个或两个以上相同的键,若出现,则执行直接报错,但值可以有相同的。在字典中,键必须是不可变的,如字符串、数字或元组,但值可以取任何数据类型。

下面是一个简单的字典示例:

>>> dict_define={'小萌': '000', '小智': '001', '小强': '002'}
>>> dict_define
{'小萌': '000', '小智': '001', '小强': '002'}

也可以为如下形式:

>>> dict_1={'abc': 456}
>>> dict_1
{'abc': 456}
>>> dict_2={'abc': 123, 98.6: 37}
>>> dict_2
{'abc': 123, 98.6: 37}

5.2.1 dict()函数

在Python中,可以用dict()函数,通过其他映射(如其他字典)或键值对建立字典,示例如下:

>>> student=[('name','小智'),('number','001')]
>>> student
[('name', '小智'), ('number', '001')]
>>> type(student)
<class 'list'>
>>> student_info=dict(student)
>>> type(student_info)
<class 'dict'>
>>> print(f'学生信息:{student_info}')
学生信息:{'name': '小智', 'number': '001'}
>>> student_name=student_info['name']
>>> print(f'学生姓名:{student_name}')
学生姓名:小智
>>> student_num=student_info['number']   #从字典中轻松获取学生序号
>>> print(f'学生序号:{student_num}')
学生学号:001

由输出结果可以看到,可以使用dict()函数将序列转换为字典。并且字典的操作很简单,5.1节中期望的功能也很容易实现。

dict函数可以通过关键字参数的形式创建字典,示例如下:

>>> student_info=dict(name='小智',number='001')
>>> print(f'学生信息:{student_info}')
学生信息:{'name': '小智', 'number': '001'}

由输出结果可以看到,通过关键字参数的形式创建了字典。

需要补充一点:字典是无序的,就是不能通过索引下标的方式从字典中获取元素,例如:

>>> student_info=dict(name='小智',number='001')
>>> student_info[1]
Traceback (most recent call last):
  File "<pyshell#139>", line 1, in <module>
    student_info[1]
KeyError: 1

由输出结果可以看到,在字典中,不能直接使用索引下标的方式(类似列表)取得字典中的元素,这是因为字典是无序的。

通过关键字创建字典是dict()函数非常有用的一个功能,应用非常便捷,在实际项目应用中,可以多加使用。

5.2.2 字典的基本操作

字典的基本操作大部分与序列(sequence)类似,字典有修改、删除等基本操作。下面逐一进行具体的讲解。

1.修改字典

字典的修改包括字典的更新和新增两个操作。

字典的更新,是指对已有键值对进行修改,操作结果是保持现有键值对数量不变,但其中某个或某几个的键、值或键值发生了变更。

字典的新增,指的是向字典添加新内容,操作的结果是在字典中增加至少一个新的键值对,键值对数量会比新增之前至少多一个。

字典的更新和新增操作示例如下:

>>> student={'小萌':'000','小智':'001','小强':'002'}
>>> print(f'更改前,student:{student}')
更改前,student:{'小萌': '000', '小智': '001', '小强': '002'}
>>> xiaoqiang_num=student['小强']
>>> print(f'更改前,小强的序号是:{xiaoqiang_num}')
更改前,小强的序号是:002
>>> student['小强']='005'  #更新小强的序号为005
>>> xiaoqiang_num=student['小强']
>>> print(f'更改后,小强的序号是:{xiaoqiang_num}')
更改后,小强的序号是:005
>>> print(f'更改后,student:{student}')
更改后,student:{'小萌': '000', '小智': '001', '小强': '005'}
>>> student['小张']='003'  #添加一个学生
>>> xiaozhang_num=student['小张']
>>> print(f'小张的序号是:{xiaozhang_num}')
小张的序号是:003
>>> print(f'添加小张后,student:{student}')
添加小张后,student:{'小萌': '000', '小智': '001', '小强': '005', '小张': '003'}

由输出结果可以看到,对字典的修改和添加操作均成功。

2.删除字典元素

此处字典元素的删除指的是显式删除,显式删除一个字典元素用del命令,操作示例如下:

>>> student={'小强': '002', '小萌': '000', '小智': '001', '小张': '003'}
>>> print(f'删除前:{student}')
删除前:{'小强': '002', '小萌': '000', '小智': '001', '小张': '003'}
>>> del student['小张']  #删除键值为“小张”的键
>>> print(f'删除后:{student}')
删除后:{'小强': '002', '小萌': '000', '小智': '001'}

由输出结果可以看到,变量student在删除前有一个键为小张,值为003的元素,执行删除键为小张的操作后,键为小张,值为003的元素就不存在了,即对应键值对被删除了。所以在字典中,可以通过删除键来删除一个字典元素。

在Python中,除了可以删除键,还可以直接删除整个字典,例如:

由输出结果可以看到,通过删除变量student,就删除了整个字典。字典删除后就不能进行访问了,这是因为执行del操作后,字典就不存在了,字典变量(如上面的student变量)也不存在了,继续访问不存在的变量,就会报变量没有定义的错误。

3.字典键的特性

在Python中,字典中的值可以没有限制地取任何值,既可以是标准对象,也可以是用户定义的对象,但键不行。

对于字典,需要强调以下两点:

(1)在一个字典中,不允许同一个键出现两次,即键不能相同。创建字典时如果同一个键被赋值两次或以上,则最后一次的赋值会覆盖前一次的赋值,示例如下:

    >>> student={'小萌': '000', '小智': '001', '小萌': '002'}  #小萌赋两次值,第一次000,
第二次002
    >>> print(f'学生信息:{student}')
    学生信息:{'小萌': '002', '小智': '001'}   #输出结果中小萌的值为002

由输出结果可以看到,示例中对键为小萌的元素做了两次赋值操作,但输出结果中只有一个键为小萌的元素,并且对应值为第二次的赋值。

(2)字典中的键必须为不可变的,可以用数字、字符串或元组充当,但不能用列表,示例如下:

由输出结果可以看到,在字典中,可以使用元组做键,因为元组是不可变的。但不能用列表做键,因为列表是可变的,使用列表做键,运行时会提示类型错误。

4.len函数

在字典中,len()函数用于计算字典中元素的个数,也可以理解为字典中键的总数,示例如下:

    >>> student={'小萌': '000', '小智': '001', '小强': '002','小张': '003', '小李':
'004'}
    >>> print(f'字典元素个数为:{len(student)}')
    字典元素个数为:5

由输出结果可以看到,通过使用len()函数,得到字典student变量中的元素个数为5。

5.type函数

type()函数用于返回输入的变量的类型,如果输入变量是字典就返回字典类型,示例如下:

    >>> student={'小萌': '000', '小智': '001', '小强': '002','小张': '003', '小李':
'004'}
    >>> print(f'字典的类型为:{type(student)}')
    字典的类型为:<class 'dict'>

由输出结果可以看到,通过type()函数得到student变量的类型为字典(dict)类型。

5.2.3 字典和列表比较

假如给你一个任务,让你从一堆名字中查找某个名字,找到名字后再找到这个名字对应的序号,名字和序号是一一对应的,就如此时在字典屋的Python快乐学习班的全体同学都有一个唯一的序号。

根据目前所学,可以有两种实现方式:list(列表)和dict(字典)。

方式一:使用list(列表)实现。如果用list实现,需要定义两个列表,一个列表存放名字,一个列表存放序号,并且两个列表中的元素有一一对应关系。使用列表的方式,要先在名字列表中找到对应的名字,再从序号列表中取出对应的序号,使用列表的方式会发现,当list列表越长时,耗时也越长。

方式二:使用dict(字典)实现。如果用dict实现,只需要一个名字和序号一一对应的字典,就可以直接根据名字查找序号,无论字典有多大,查找速度都不会变。

为什么dict查找速度这么快?

因为在Python中,dict字典的实现原理和查字典类似,而list的实现原理则和标准的复读机类似,只能从左往右,一个不漏地读一遍。假设字典包含10000个汉字,要查某一个汉字时,一种方法是把字典从第一页往后翻,每一页从左到右,从上往下查找,直到找到想要的汉字为止,这种方式就是在list中查找元素的方式,所以当list越大时,查找会越慢。另一种方法是在字典的索引表里(如部首表)查这个汉字对应的页码,然后直接翻到该页找到这个汉字。用这种方式,无论找哪个汉字,查找速度都会非常快,不会随着字典大小的增加而变慢。

dict就是第二种实现方法,给定一个名字,比如要查找5.2.2节中,变量student中“小萌”的序号,在dict内部就可以直接计算出“小萌”存放序号的“页码”,也就是000存放的内存地址,直接取出来即可,所以速度非常快。

综上所述,list和dict各有以下几个特点。

字典dict的特点是:

(1)查找和插入的速度极快,不会随着字典中键的增加而变慢。

(2)字典需要占用大量内存,内存浪费多。

(3)字典中的元素是无序的,即不能通过索引下标的方式从字典中取元素。

列表list的特点是:

(1)查找和插入时间随着列表中元素的增加而增加。

(2)列表占用空间小,浪费内存很少。

(3)列表的元素是有序的,即可以通过索引下标从列表中取元素。

所以,字典dict可以理解为通过空间换取时间,而列表list则是通过时间换取空间的。

字典dict可以用在很多需要高速查找的地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记dict的键必须是不可变对象。

提示

dict内部存放的顺序和键放入的顺序没有关系。