5.2 创建和使用字典
字典的创建格式如下:
>>> d = {key1 : value1, key2 : value2 }
字典由多个键及其对应的值构成的对组成(把键/值对称为项)。字典的每个键/值(key/value)对用冒号(:)分割,每个项之间用逗号(,)分割,整个字典包括在花括号({})中。空字典(不包括任何项)由两个大括号组成,如{}。
键必须是唯一的,但值不必。值可以取任何数据类型,键必须是不可变的,如字符串、数字或元组。
下面是一个简单的字典示例:
>>> dict_val = {'小萌': '1001', '小智': '1002', '小强': '1003'}
也可以为如下形式:
>>> dict1 = { 'abc': 456 } >>> dict2 = { 'abc': 123, 98.6: 37 }
5.2.1 dict函数
可以用dict函数通过其他映射(如其他字典)或键/值序列对建立字典,例如:
>>> student=[('name','小萌'),('number','1001')] >>> detail=dict(student) >>> print('学生详细信息:',detail) 学生详细信息: {'name': '小萌', 'number': '1001'} >>> print('学生姓名:',detail['name']) 学生姓名: 小萌 >>> print('学生学号:',detail['number']) 学生学号: 1001
由输出结果看到,dict函数可以将序列转换为字典。字典的操作很简单,在5.1节期望的功能已经实现了。
dict函数可以通过关键字参数创建字典,例如:
>>> detail=dict(name='小智',number='1002') >>> print('学生详细信息:',detail) 学生详细信息: {'name': '小智', 'number': '1002'}
由输出结果看到,通过关键字参数创建了字典。
通过关键字创建字典是dict函数非常有用的一个功能,可以多加运用。
5.2.2 字典的基本操作
字典的基本操作在很多方面与序列(sequence)类似,支持修改、删除等操作。下面进行具体的讲解。
1. 修改字典
向字典添加新内容的方法是增加新键/值对,修改或删除已有键/值对,例如:
>>> student={'小萌':'1001','小智':'1002','小强':'1003'} >>> student['小强']='1005' #更新小强的学号 >>> print('小强的学号是:%(小强)s' % student) 小强的学号是:1005 >>> student['小张']='1006' #添加一个学生 >>> print('小张的学号是:%(小张)s' % student) 小张的学号是:1006
由输出结果看到,修改和添加均操作成功。
2. 删除字典元素
此处的删除指的是显式删除,显式删除一个字典用del命令,例如:
>>> student={'小强': '1005', '小萌': '1001', '小智': '1002', '小张': '1006'} >>> print('删除前:',student) 删除前: {'小强': '1005', '小萌': '1001', '小智': '1002', '小张': '1006'} >>> del student['小张'] #删除键值为“小张”的键 >>> print('删除后:',student) 删除后: {'小强': '1005', '小萌': '1001', '小智': '1002'}
由输出结果看到对应键/值被正确删除了。
除了删除键外,还可以删除整个字典,例如:
>>> student={'小强': '1005', '小萌': '1001', '小智': '1002', '小张': '1006'} >>> print('删除前:',student) 删除前: {'小强': '1005', '小萌': '1001', '小智': '1002', '小张': '1006'} >>> del student #删除字典 >>> print('删除后:',student) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'student' is not defined
由输出结果看到,删除字典后就不能对字典进行访问了,因为执行del操作后字典就不存在了,因而会报变量没有定义的错误。
3. 字典键的特性
字典值可以没有限制地取任何Python对象,既可以是标准对象,也可以是用户定义的对象,但键不行。
需要记住以下两点:
(1)不允许同一个键出现两次。创建时如果同一个键被赋值两次,后面的值会被记住,例如:
>>> student={'小萌': '1001', '小智': '1002', '小萌': '1005'} >>> print('学生信息:',student) 学生信息: {'小萌': '1005', '小智': '1002'}
由输出结果看到,一个键被赋值两次,后面的值会被记住。
(2)键必须不可变,可以用数字、字符串或元组充当,不能用列表,例如:
>>> field={['name']:'小萌','number':'1001'} Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'list'
由输出结果看到,不能用列表做键,否则会提示类型错误。
4. len函数
len(dict)函数用于计算字典元素的个数,即键的总数,例如:
>>> student={'小萌': '1001', '小智': '1002', '小强': '1005','小张': '1006'} >>> print('字典元素个数为:%d个' % len(student)) 字典元素个数为:4个
输出结果得到字典元素的个数为4。
5. type函数
type(variable)函数返回输入的变量类型,如果输入的变量是字典,就返回字典类型,例如:
>>> student={'小萌': '1001', '小智': '1002', '小强': '1005','小张': '1006'} >>> print('字典的类型为:',type(student)) 字典的类型为: <class 'dict'>
输出结果为字典(dict)类型。
5.2.3 字典的格式化字符串
我们已经在第4章见过如何使用字符串格式化功能格式化元组中的所有值。如果使用字典(只以字符串作为键)而不是元组做这项工作,会使字符串格式化更有趣一些,例如:
>>> student={'小萌':'1001','小智':'1002','小强':'1003'} >>> print('小强的学号是:%(小强)s' % student) 小强的学号是:1003
由操作结果看到,字典的格式化方式是在每个转换说明符中的%字符后加上用圆括号括起来的键,再跟上其他说明元素。
字典的格式化除了增加字符串键外,转换说明符还像以前一样工作。以这种方式使用字典时,只要所有给出的键都能在字典中找到,就可以获得任意数量的转换说明符。
5.2.4 字典和列表的区别
例如,以一个名字查找对应的学号。
如果用list实现,就要先在名字列表中找到对应的名字,再从学号列表取出对应的学号,list越长耗时越长。如果用dict实现,只需要一个名字和学号的对照表,就可以直接根据名字查找学号,无论这个表有多大,查找速度都不会变慢。
为什么dict查找速度这么快?
因为dict的实现原理和查字典一样。假设字典包含10 000个汉字,我们要查某一个字,一种方法是把字典从第一页往后翻,直到找到我们想要的字为止,这种方法是在list中查找元素,list越大查找越慢。另一种方法是在字典的索引表里(如部首表)查这个字对应的页码,然后直接翻到该页找到这个字。无论找哪个字,这种查找速度都非常快,不会随着字典大小的增加而变慢。
dict就是第二种实现方法,给定一个名字,比如我们要查找5.2.3小节示例中“小萌”的学号,在dict内部就可以直接计算出“小萌”存放学号的“页码”,也就是1001存放的内存地址,直接取出来即可,所以速度非常快。
综上所述,list和dict各有以下几个特点。
dict的特点是:
(1)查找和插入的速度极快,不会随着key的增加而变慢。
(2)需要占用大量内存,内存浪费多。
list的特点是:
(1)查找和插入时间随着元素的增加而增加。
(2)占用空间小,浪费内存很少。
所以,dict是使用空间换取时间。
dict可以用在很多需要高速查找的地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记dict的键必须是不可变对象。
提 示
dict内部存放的顺序和键放入的顺序没有关系。