《手把手陪您学Python》22——字典

在上一篇《手把手陪您学Python》21——元组中,我们学习了元组的定义、操作方法以及元组“拆包”的方法和应用。今天,将要给大家介绍的数据结构是字典。

如果说以前我们学习的列表、元组都是一维的数据序列,那么字典的数据结构包括其展现形式就是二维的,因为字典的每一个元素都是由键和值组成的键值对,因此形成了两个维度,由此也极大地扩展了Python的应用场景和我们编程的自由度。

1、字典的定义

字典是由一对大扩号{}括起来的键值对的数据集合。每个键(key)和值(value)之间用“:”分隔,每个键值对之间用“,”分隔,每个字典中键值对的数量没有限制。字典的语法格式如下所示:

dict = {key1:value1, key2:value2, key3:value3}

字典中的键必须是唯一的,能够作为键的数据类型必须是不可变的,如字符串、数字、元组等。

字典中的值可以重复,而且可以是任何的数据类型,如字符串、数字、元组、列表、字典,以及我们后面将要介绍的集合等。

In [1]: dict1 = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephont'}   # 是不是很像“字典”?
        dict1
Out[1]: {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephont'}

In [2]: dict2 = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephont', 'A': 'Aillgater'}   # 当键重复时不会报错,但是只有后一个值会被记住
        dict2
Out[2]: {'A': 'Aillgater', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephont'}

In [3]: dict3 = {1: 'Apple', 'B': 1, ('C', 2): True, '3': ['Dog', 4, False], (1, '2', 'ASD): (Elephont,), (1, 2, (1, 2)): 'Apple'}   # 各种不同数据类型的键和值,且值可以重复
        dict3
Out[3]: {1: 'Apple',
         'B': 1,
         ('C', 2): True,
         '3': ['Dog', 4, False],
         (1, '2', 'ASD'): ('Elephont',),
         (1, 2, (1, 2)): 'Apple'}
         
In [4]: dict4 = {}   # 定义空字典
        dict4
Out[4]: {}

↓↓↓**********扩展内容**********↓↓↓

从这篇文章开始,将会增加一些扩展内容的讲解,并使用上面的这种符号,将该部分内容进行区分,给一些学有余力的朋友扩展或者深入学习。对于其他朋友,可以选择暂时跳过该部分内容,也完全不会对后面的学习造成任何影响,大家可以放心。

这里补充的是,在上一篇《手把手陪您学Python》21——元组中我们说过,虽然元组是不能被修改的,但是可以对元组元素内部的对象进行修改。虽然也是元组,但是这种类型的元组,也是不能作为字典的键的。

In [5]: dict5 = {'B': 1, (1, 2, [1, 2]): 'Apple'}   # 从第三个实例的元组嵌套元组变成了元组嵌套列表
Out[5]: ---------------------------------------------------------------------------
        TypeError                                 Traceback (most recent call last)
        in
        ----> 1 dict5 = {'B': 1, (1, 2, [1, 2]): 'Apple'}   # 从第三个实例的元组嵌套元组变成了元组嵌套列表

        TypeError: unhashable type: 'list'

从上可以看到是unhashable类型的错误,也就是说list是不能被哈希化的。所谓不能哈希化,就是说不能作为字典的键。

这里再给大家介绍一个简单的函数hash(),可以判断一个对象是否是不可变的,或者说一个对象是否可以作为字典的键。如果有返回值,则说明该对象是不可变的,可以作为字典的键,如果报错,则说明该对象是可变的,不能作为字典的键。

In [6]: hash((1, 2, [1, 2]))   # 报错,说明不能作为字典的键
Out[6]: ---------------------------------------------------------------------------
        TypeError                                 Traceback (most recent call last)
        in
        ----> 1 hash((1, 2, [1, 2]))   # 报错,说明不能作为字典的键

        TypeError: unhashable type: 'list'

了解了这些内容之后,我们就可以从更专业的角度去理解字典的这样一种数据结构了。字典是python语言中唯一的映射类型。映射类型对象里哈希值(键,key)和指向的对象(值,value)是一对多的关系,所以字典也可以被理解为可变的哈希表。

为了让大家能够明白字典这样一种比较特殊的数据类型,以及只有不可变的对象才能够作为字典的键的原理,上面这段内容讲的稍微有些深入。这如果大家看起来有些费力,可以暂时略过。能够看懂的朋友们,还可以再试一下能够被哈希化,或者说可以作为字典的键的对象,hash()函数后的返回值是怎么样的(例如:hash('A'))。

↑↑↑**********扩展内容**********↑↑↑

字典和列表一样是可变的,可以进行增删改等操作。同时,字典又是相对无序的,因此不能用切片和索引的方式进行查找或者部分截取。下面,我们将分别讲一下字典增删改查的各种操作。

2、字典的查找

字典的查找非常有意思,与我们之前切片和索引的方法完全不同,而是和我们查找字典一样,先找到一个关键值(键key),再通过这个关键值找到值(value)。就像我们浏览网页的输入网址访问网页一样,所以字典的查找过程也是一个访问过程。

访问字典值的方法是将要查找的值(value)的键(key)放在方括号里,就像我们索引时将位置数值放在方括号里一样,得到的返回值就是这个键(key)对应的值(value)。

In [7]: dict6 = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephont'}  

In [8]: print("dict6['A']: {},dict6['C']: {}。".format(dict6['A'], dict6['C']))   # 访问的键如果存在于字典中,就返回键对应的值
Out[8]: dict6['A']: Apple,dict6['C']: Cat。

In [9]: dict6['F']   # 访问的键如果不存在于字典中,就报错
Out[9]: ---------------------------------------------------------------------------
        KeyError                                  Traceback (most recent call last)
        <ipython-input-16-6d56e56ab35b> in <module>
        ----> 1 dict6['F']   # 访问的键如果不存在于字典中,就报错

        KeyError: 'F'

3、字典的增删改

在字典中添加键值对的方法非常简单,就是直接给字典新的键赋值就可以。如果该键已经存在,那么这个键原来的值会被覆盖,替换成新的值,相当于修改。

In [10]: dict6['F'] = 'Fox'   # 新的键值对会被添加到字典中
         dict6
Out[10]: {'A': 'Apple',
          'B': 'Ball',
          'C': 'Cat',
          'D': 'Dog',
          'E': 'Elephont',
          'F': 'Fox'}
In [11]: dict6['A'] = 'Aillgater'   # 新的值会替换原来键'A'对应的值'Apple',即修改
         dict6
Out[11]: {'A': 'Aillgater',
          'B': 'Ball',
          'C': 'Cat',
          'D': 'Dog',
          'E': 'Elephont',
          'F': 'Fox'}

删除字典,既可以删除字典中的某一个键值对,也可以清空字典(字典仍然存在),使其变成“空字典”,或者直接将字典删除(字典不存在了)。

In [12]: del dict6['A']   # 删除键值对
         dict6
Out[12]: {'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephont', 'F': 'Fox'}

In [13]: dict6.clear()   # 清空字典,但字典仍然存在,是一个空字典
         dict6
Out[13]: {}

In [14]: del dict6   # 删除字典,字典不存在了
         dict6
Out[14]: ---------------------------------------------------------------------------
         NameError                                 Traceback (most recent call last)
         in
               1 del dict6   # 删除字典,字典不存在了
         ----> 2 dict6
         
         NameError: name 'dict6' is not defined

4、字典的函数

涉及字典的函数并不多,包括计算字典键值对个数的len(),以及将字典转化成字符串的str()。其中,str()是我们之前学习过的函数,还可以将数字、列表、元组等转化成字符串进行输出。

对于普通的字典来说,这两个函数很容易,都不需要举例。这里我们看看当字典中包括重复的键时,会有什么样的结果。

In [15]: dict7 = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephont', 'A': 'Aillgater'}

In [16]: len(dict7)
Out[16]: 5

In [17]: str(dict7)
Out[17]: "{'A': 'Aillgater', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephont'}"

5、字典的方法

字典有很多方法,而且非常重要,像.keys()、.values(),都是在使用字典进行编程时少不了的方法,同时还有.pop()、.update()等等,也都会经常使用。下面我们就来详细介绍一下字典的各类方法。

按照惯例,还是先将菜鸟教程中字典的各类方法进行列示,如有需要,可以直接点击链接查看。后面将对几种重要的方法进行介绍和举例。

序号

函数及描述

1

radiansdict.clear()

删除字典内所有元素

2

radiansdict.copy()

返回一个字典的浅复制

3

radiansdict.fromkeys()

创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值

4

radiansdict.get(key, default=None)

返回指定键的值,如果值不在字典中返回default值

5

key in dict

如果键在字典dict里返回true,否则返回false

6

radiansdict.items()

以列表返回可遍历的(键, 值) 元组数组

7

radiansdict.keys()

返回一个迭代器,可以使用 list() 来转换为列表

8

radiansdict.setdefault(key, default=None)

和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default

9

radiansdict.update(dict2)

把字典dict2的键/值对更新到dict里

10

radiansdict.values()

返回一个迭代器,可以使用 list() 来转换为列表

11

pop(key[,default])

删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。否则,返回default值。

12

popitem()

随机返回并删除字典中的最后一对键和值。

刚才说到,.keys()和.values()是字典最重要的两个方法,他们的作用是分别提供字典键和值的迭代器,通俗的说就是会分别输出字典所有的键和所有的值。

In [18]: dict8 = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephont'}

In [19]: list(dict8.keys())
Out[19]: ['A', 'B', 'C', 'D', 'E']

In [20]: list(dict8.values())
Out[20]: ['Apple', 'Ball', 'Cat', 'Dog', 'Elephont']

In [21]: list(dict8)   # 当.keys()或.values()被省略时,其作用与写上.keys()相同
Out[21]: ['A', 'B', 'C', 'D', 'E']

In [22]: tuple(dict8)   # 转化成元组输出也是这样
Out[22]: ('A', 'B', 'C', 'D', 'E')

In [23]: str(dict8)   # 但转化成字符串输出就不一样了
Out[23]: "{'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephont'}"

在上面的实例中,我们没有直接返回dict8.keys()或者dict8.values()的结果,而是将其转化成list进行输出。这是因为dict8.keys()返回的是字典键的迭代器,而不是一种数据结构。将其转化成列表或者元组进行输出,可以让我们在后续的代码中更好地对字典的键进行操作,也可以利用列表和元组的特性进行开发。

但并不是说这种dict8.keys()这种迭代器的结果不可以输出,只不过这种迭代器会更多地用于for循环等的迭代,而不是直接地输出或者下一步代码的数据输入。

In [24]: dict8.keys()   # 返回值是一个迭代器
Out[24]: dict_keys(['A', 'B', 'C', 'D', 'E'])

In [25]: for letter in dict8.keys():
             print(letter)
Out[25]: A
         B
         C
         D
         E

上面仅仅是利用字典.keys()方法作为迭代器的一个简单示例,在下一篇中,我们还会对字典的.keys()方法和.values()方法进行深入探讨,看看利用这些方法能够开发出哪些有意思的小程序。

下面再通过几个实例介绍一下另外几个比较重要的方法。

In [26]: seq = ('A', 'B', 'C', 'D', 'E')   # 当val省略时,字典中各个键对应的值都为空
         dict.fromkeys(seq)   # 从一个序列生成字典,序列值为字典的键
Out[26]: {'A': None, 'B': None, 'C': None, 'D': None, 'E': None}

In [27]: seq = ('A', 'B', 'C', 'D', 'E')   # 当val为某个值时,字典中各个键对应的值都为该值
         dict.fromkeys(seq, (1 ,2))
Out[27]: {'A': (1, 2), 'B': (1, 2), 'C': (1, 2), 'D': (1, 2), 'E': (1, 2)}

In [28]: dict9 = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephont'}
         'F' in dict9   # 判断一个字典中是否存在某个键
Out[28]: False

In [29]: dict9.pop('A')   # 注意与上面讲的del的区别,pop方法会在删除键值对的同时返回被删除的键对应的值,而del只是删除键值对没有返回值
Out[29]: 'Apple'

In [30]: dict9
Out[30]: {'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephont'}

In [31]: dict9.update({'A': 'Aillgater', 'F': 'Fox'})   # 合并两个字典,对于原字典中已经存在的键,当update()中的字典也存在相同的键,新的值会覆盖原来的值。
         dict9
Out[31]: {'B': 'Ball',
          'C': 'Cat',
          'D': 'Dog',
          'E': 'Elephont',
          'A': 'Aillgater',
          'F': 'Fox'}

以上就是本篇文章对于字典介绍的内容。由于字典非常重要,在介绍字典的其它应用时,又需要使用到几个我们没有学过的函数,篇幅有些长,不便于大家的阅读和学习。因此,将字典分成了两篇文章进行介绍。下一篇中,会先给大家介绍几个非常常用的Python内置序列函数,之后再利用这几个函数给大家介绍字典的其它应用场景,敬请关注。


感谢阅读本文!如有任何问题,欢迎留言,一起交流讨论^_^

要阅读《手把手陪您学Python》系列文章的其他篇目,请关注公众号点击菜单选择,或点击下方链接直达。

《手把手陪您学Python》1——为什么要学Python?

《手把手陪您学Python》2——Python的安装

《手把手陪您学Python》3——PyCharm的安装和配置

《手把手陪您学Python》4——Hello World!

《手把手陪您学Python》5——Jupyter Notebook

《手把手陪您学Python》6——字符串的标识

《手把手陪您学Python》7——字符串的索引

《手把手陪您学Python》8——字符串的切片

《手把手陪您学Python》9——字符串的运算

《手把手陪您学Python》10——字符串的函数

《手把手陪您学Python》11——字符串的格式化输出

《手把手陪您学Python》12——数字

《手把手陪您学Python》13——运算

《手把手陪您学Python》14——交互式输入

《手把手陪您学Python》15——判断语句if

《手把手陪您学Python》16——循环语句while

《手把手陪您学Python》17——循环的终止

《手把手陪您学Python》18——循环语句for

《手把手陪您学Python》19——第一阶段小结

《手把手陪您学Python》20——列表

《手把手陪您学Python》21——元组

For Fans:关注“亦说Python”公众号,回复“手22”,即可免费下载本篇文章所用示例语句。

亦说Python——Python爱好者的学习分享园地
 

猜你喜欢

转载自blog.csdn.net/mnpy2019/article/details/102607566