Python从入门到精通
上QQ阅读APP看书,第一时间看更新

6.1 字典

字典(dictionary)和列表类似,也是可变序列,不过与列表不同,它是无序的可变序列,保存的内容是以“键-值对”的形式存放的。这类似于《新华字典》,它可以把拼音和汉字关联起来。通过音节表可以快速找到想要的汉字。其中,《新华字典》里的音节表相当于键(key),而对应的汉字相当于值(value)。键是唯一的,而值可以有多个。字典在定义一个包含多个命名字段的对象时,很有用。

说明

Python中的字典相当于Java或者C++中的Map对象。

字典的主要特征如下。

 通过键而不是通过索引来读取

字典有时也称为关联数组或者散列表(hash)。它是通过键将一系列的值联系起来的,这样就可以通过键从字典中获取指定项,但不能通过索引来获取。

 字典是任意对象的无序集合

字典是无序的,各项是从左到右随机排序的,即保存在字典中的项没有特定的顺序。这样可以提高查找顺序。

 字典是可变的,并且可以任意嵌套

字典可以在原处增长或者缩短(无须生成一份拷贝),并且它支持任意深度的嵌套(即它的值可以是列表或者其他的字典)。

 字典中的键必须唯一

不允许同一个键出现两次,如果出现两次,则后一个值会被记住。

 字典中的键必须不可变

字典中的键是不可变的,所以可以使用数字、字符串或者元组,但不能使用列表。

6.1.1 字典的创建和删除

定义字典时,每个元素都包含两个部分——“键”和“值”,并且在“键”和“值”之间使用冒号分隔,相邻两个元素使用逗号分隔,所有元素放在一个大括号“{}”中。语法格式如下:

    dictionary = {'key1':'value1', 'key2':'value2', ..., 'keyn':'valuen',}

参数说明如下:

 dictionary:表示字典名称;

 key1, key2, ..., keyn:表示元素的键,必须是唯一的,并且不可变,例如可以是字符串、数字或者元组;

 value1, value2, ..., valuen:表示元素的值,可以是任何数据类型,不是必须唯一。

例如,创建一个保存通讯录信息的字典,可以使用下面的代码。

01  dictionary = {'qq':'84978981','明日科技':'84978982','无语':'0431-84978981'}
02  print(dictionary)

执行结果如下:

    {'qq': '84978981', '明日科技': '84978982', '无语': '0431-84978981'}

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

    dictionary = {}

或者

    dictionary = dict()

Python的dict()方法除了可以创建一个空字典外,还可以通过已有数据快速创建字典。主要表现为以下两种形式。

1.通过映射函数创建字典

语法如下:

    dictionary = dict(zip(list1,list2))

参数说明如下:

 dictionary:表示字典名称。

 zip()函数:用于将多个列表或元组对应位置的元素组合为元组,并返回包含这些内容的zip对象。如果想得到元组,可以将zip对象使用tuple()函数转换为元组;如果想得到列表,则可以使用list()函数将其转换为列表。

说明

在Python 2.x中,zip()函数返回的内容为包含元组的列表。

 list1:表示一个列表,用于指定要生成字典的键。

 list2:表示一个列表,用于指定要生成字典的值。如果list1和list2的长度不同,则与最短的列表长度相同。

场景模拟:某大学的寝室里住着4位清秀可人的美女,她们的名字保存在一个列表中,另外,她们每个人的星座对应着保存在另一个列表中。

【例6.1】 根据名字和星座创建一个字典。(实例位置:资源包\TM\sl\06\01)

在IDLE中创建一个名称为sign_create.py的文件,然后在该文件中定义两个包括4个元素的列表,再应用dict()函数和zip()函数将前两个列表转换为对应的字典,并且输出该字典,代码如下:

运行代码后,将显示如图6.1所示的结果。

图6.1 创建字典

2.通过给定的“键-值对”创建字典

语法如下:

    dictionary = dict(key1=value1,key2=value2,...,keyn=valuen)

参数说明如下:

 dictionary:表示字典名称;

 key1, key2, ..., keyn:表示元素的键,必须是唯一的,并且不可变,例如可以是字符串、数字或者元组;

 value1, value2, ..., valuen:表示元素的值,可以是任何数据类型,不是必须唯一。

例如,将实例6.1中的名字和星座通过“键-值对”的形式创建一个字典,可以使用下面的代码。

01  dictionary =dict(绮梦 = '水瓶座', 冷伊一 = '射手座', 香凝 = '双鱼座', 黛兰 = '双子座')
02  print(dictionary)

在Python中,还可以使用dict对象的fromkeys()方法创建值为空的字典,语法如下:

    dictionary = dict.fromkeys(list1)

参数说明如下:

 dictionary:表示字典名称;

 list1:作为字典的键的列表。

例如,创建一个只包括名字的字典,可以使用下面的代码。

执行结果如下。

    {'绮梦': None, '冷伊一': None, '香凝': None, '黛兰': None}

另外,还可以通过已经存在的元组和列表创建字典。例如,创建一个保存名字的元组和保存星座的列表,通过它们创建一个字典,可以使用下面的代码。

执行结果如下:

{('绮梦', '冷伊一', '香凝', '黛兰'): ['水瓶座', '射手座', '双鱼座', '双子座']}

如果将作为键的元组修改为列表,再创建一个字典,代码如下:

执行结果如图6.2所示。

图6.2 将列表作为字典的键产生的异常

同列表和元组一样,不再需要的字典也可以使用del命令删除。例如,通过下面的代码即可将已经定义的字典删除。

    del dictionary

另外,如果只是想删除字典的全部元素,可以使用字典对象的clear()方法。执行clear()方法后,原字典将变为空字典。例如,下面的代码将清除字典的全部元素。

    dictionary.clear()

除了上面介绍的方法可以删除字典元素,还可以使用字典对象的pop()删除并返回指定“键”的元素,以及使用字典对象的popitem()方法删除并返回字典中的一个元素。

6.1.2 访问字典

在Python中,如果想将字典的内容输出也比较简单,可以直接使用print()函数。例如,要想打印实例6.1中定义的dictionary字典,则可以使用下面的代码。

    print(dictionary)

执行结果如下:

    {'绮梦': '水瓶座', '冷伊一': '射手座', '香凝': '双鱼座', '黛兰': '双子座'}

但是,在使用字典时,很少直接输出它的内容。一般需要根据指定的键得到相应的结果。在Python中,访问字典的元素可以通过下标的方式实现,与列表和元组不同,这里的下标不是索引号,而是键。例如,想要获取“冷伊一”的星座,可以使用下面的代码。

    print(dictionary['冷伊一'])

执行结果如下:

    射手座

在使用该方法获取指定键的值时,如果指定的键不存在,将抛出如图6.3所示的异常。

图6.3 获取指定键不存在时抛出异常

在实际开发中,很可能我们不知道当前存在什么键,所以需要避免该异常的产生。具体的解决方法是使用if语句对不存在的情况进行处理,即给一个默认值。例如,可以将上面的代码修改为以下内容。

    print("冷伊的星座是:",dictionary['冷伊'] if '冷伊' in dictionary else '我的字典里没有此人')

当“冷伊”不存在时,将显示以下内容。

    冷伊的星座是:我的字典里没有此人

另外,Python中推荐的方法是使用字典对象的get()方法获取指定键的值。其语法格式如下:

    dictionary.get(key[,default])

其中,dictionary为字典对象,即要从中获取值的字典;key为指定的键;default为可选项,用于当指定的键不存在时,返回一个默认值,如果省略,则返回None。

例如,通过get()方法获取“冷伊一”的星座,可以使用下面的代码。

    print("冷伊一的星座是:",dictionary.get('冷伊一'))

执行结果如下。

    冷伊一的星座是: 射手座

说明

为了解决在获取指定键的值时,因不存在该键而导致抛出异常,可以为get()方法设置默认值,这样当指定的键不存在时,得到结果就是指定的默认值。例如,将上面的代码修改为以下内容。

    print("冷伊的星座是:",dictionary.get('冷伊','我的字典里没有此人'))

将得到以下结果。

    冷伊的星座是:我的字典里没有此人

场景模拟:仍然是某大学寝室里的4位美女,这次将她们的名字和星座保存在一个字典里,然后再定义一个保存各个星座性格特点的字典,根据这两个字典取出某位美女的性格特点。

【例6.2】 根据星座测试性格特点。(实例位置:资源包\TM\sl\06\02)

在IDLE中创建一个名称为sign_get.py的文件,然后在该文件中创建两个字典,一个保存名字和星座,另一个保存星座和性格特点,最后从这两个字典中取出相应的信息组合出想要的结果,并输出,代码如下:

运行代码后,将显示如图6.4所示的结果。

图6.4 输出某人的星座和性格特点

6.1.3 遍历字典

字典是以“键-值对”的形式存储数据的,所以就可能需要对这些“键-值对”进行获取。Python提供了遍历字典的方法,通过遍历可以获取字典中的全部“键-值对”。

使用字典对象的items()方法可以获取字典的“键-值对”列表。其语法格式如下:

    dictionary.items()

其中,dictionary为字典对象;返回值为可遍历的“键-值对”元组列表。想要获取到具体的“键-值对”,可以通过for循环遍历该元组列表。

例如,定义一个字典,然后通过items()方法获取“键-值对”的元组列表,并输出全部“键-值对”,代码如下:

01  dictionary = {'qq':'84978981','明日科技':'84978982','无语':'0431-84978981'}
02  for item in dictionary.items():
03      print(item)

执行结果如下:

    ('qq', '84978981')
    ('明日科技', '84978982')
    ('无语', '0431-84978981')

上面的示例得到的是元组中的各个元素,如果想要获取到具体的每个键和值,可以使用下面的代码进行遍历。

01  dictionary = {'qq':'4006751066','明日科技':'0431-84978982','无语':'0431-84978981'}
02  for key,value in dictionary.items():
03      print(key,"的联系电话是",value)

执行结果如下:

    qq的联系电话是 4006751066
    明日科技 的联系电话是 0431-84978982
    无语 的联系电话是 0431-84978981

说明

在Python中,字典对象还提供了values()和keys()方法,用于返回字典的“值”和“键”列表,它们的使用方法同items()方法类似,也需要通过for循环遍历该字典列表,获取对应的值和键。

6.1.4 添加、修改和删除字典元素

由于字典是可变序列,所以可以随时在其中添加“键-值对”,这和列表类似。向字典中添加元素的语法格式如下:

    dictionary[key] = value

参数说明如下:

 dictionary:表示字典名称;

 key:表示要添加元素的键,必须是唯一的,并且不可变,例如可以是字符串、数字或者元组;

 value:表示元素的值,可以是任何数据类型,不是必须唯一。

例如,还是以之前的保存4位美女星座的场景为例,在创建的字典中添加一个元素,并显示添加后的字典,代码如下:

01  dictionary =dict((('绮梦', '水瓶座'),('冷伊一','射手座'), ('香凝','双鱼座'), ('黛兰','双子座')))
02  dictionary["碧琦"] = "巨蟹座"   # 添加一个元素
03  print(dictionary)

执行结果如下:

{'绮梦': '水瓶座', '冷伊一': '射手座', '香凝': '双鱼座', '黛兰': '双子座', '碧琦': '巨蟹座'}

从上面的结果中,可以看出又添加了一个键为“碧琦”的元素。

由于在字典中,“键”必须是唯一的,所以如果新添加元素的“键”与已经存在的“键”重复,那么将使用新的“值”替换原来该“键”的值,这也相当于修改字典的元素。例如,再添加一个“键”为“香凝”的元素,这次设置她为“天蝎座”。可以使用下面的代码。

01  dictionary =dict((('绮梦', '水瓶座'),('冷伊一','射手座'), ('香凝','双鱼座'), ('黛兰','双子座')))
02  dictionary["香凝"] = "天蝎座"   # 添加一个元素,当元素存在时,则相当于修改功能
03  print(dictionary)

执行结果如下:

    {'绮梦': '水瓶座', '冷伊一': '射手座', '香凝': '天蝎座', '黛兰': '双子座'}

从上面的结果可以看出,并没有添加一个新的“键”为“香凝”的元素,而是直接对“香凝”进行了修改。

当字典中的某个元素不需要时,可以使用del命令将其删除。例如,要删除字典dictionary的键为“香凝”的元素,可以使用下面的代码。

01  dictionary =dict((('绮梦', '水瓶座'),('冷伊一','射手座'), ('香凝','双鱼座'), ('黛兰','双子座')))
02  del dictionary["香凝"]    # 删除一个元素
03  print(dictionary)

执行结果如下:

    {'绮梦': '水瓶座', '冷伊一': '射手座', '黛兰': '双子座'}

从上面的执行结果中可以看到,在字典dictionary中只剩下3个元素了。

注意

当删除一个不存在的键时,将抛出如图6.5所示的异常。

图6.5 删除一个不存在的键时将抛出的异常

因此,需要将上面的代码修改为以下内容,从而防止删除不存在的元素时抛出异常。

6.1.5 字典推导式

使用字典推导式可以快速生成一个字典,它的表现形式和列表推导式类似。例如,我们可以使用下面的代码生成一个包含4个随机数的字典,其中字典的键使用数字表示。

执行结果如下:

    生成的字典为: {1: 21, 2: 85, 3: 11, 4: 65}

另外,使用字典推导式也可根据列表生成字典。例如,可以将实例6.2修改为通过字典推导式生成字典。

【例6.3】 根据名字和星座创建一个字典(副本)。(实例位置:资源包\TM\sl\06\03)

在IDLE中创建一个名称为sign_create.py的文件,然后在该文件中定义两个包括4个元素的列表,再应用dict()函数和zip()函数将两个列表转换为对应的字典,并且输出该字典,代码如下:

运行代码后,将显示如图6.6所示的结果。

图6.6 采用字典推导式创建字典