到现在我们已经学习了python中的很多“数据类型”了,比较简单的像int、float及str,稍微复杂的如list和tuple等,那接下来我们再讲一种我认为是在数据分析中非常有用的数据类型——字典;说到字典,我们小时候肯定用过《新华字典》、《英汉字典》,那python中的这个“数据类型”被称为字典是不是和我们之前天天翻的字典有什么关系呢?的确,“字典”并不是我们凭空翻译过来的,这个类型就是英文中的“dictionary”;接下来我们简单说一下这个数据类型为什么叫字典;首先我们肯定知道在数学中学过的一种关系叫做“映射关系”:
集合A内的小写字母都会一一映射到集合B内的大写字母,而且上图的每个小写字母都只能对应一个大写字母(这是肯定的);再举一个生动些的例子,我们都知道每代iphone手机都会有它的slogan(标语):
我们是可以通过找到iphone的型号,进而检索到它相应的标语,也就好比我们可以通过《英汉词典》中的一个英文单词来检索到它的中文含义;所以这就是为什么这种“数据类型”被称为字典的原因。
另外我们也通常将“字典”称为“键值对”,就好比我们可以把“iPhone5s”称为“键”(key),把它对应的标语“超前 空前”称为“值”(value),并且每一个键和值的组合(key-value)我们都称为“项”,下面我们演示一下字典的用法。
9.1 创建字典的多种方法
首先定义一个空字典
dict1 = {}print(type(dict1))
结果:
很显然定义字典的方式是使用花括号“{}”,并且输出的数据类型名为“dict”;那接下来我们试一下将历代iphone及其slogan置入字典再进行检索:
dict_iphone = {'iphone 4s':'迄今为止最惊人的iphone','iphone 5':'这一次一切皆有可能'}print(dict_iphone['iphone 5'])
结果:
这一次一切皆有可能
从上面的演示可以看出,在定义字典时,键和值之间需要使用“:”连接,并且项与项之间使用“,”分隔(当然单引号只是为了定义字符串,并不是字典的一部分),我们或许还注意到一个特点,字典跟列表不同,列表讲究顺序,而字典讲究映射,对顺序并无要求,所以字典在检索时会更简洁。
另外还需要注意的一点:字典的键(key)必须是独一无二的,而值可以取任何数据类型,但必须是不可变的。
当然我们也可以使用dict()方法来创建字典:
dict1 = dict((('4s',4999),('5',5999),('5s',6999)))print(dict1)
结果:
{'4s': 4999, '5': 5999, '5s': 6999}
这里我们会发现dict方法后有很多层小括号,所以一定不要搞晕,第一层小括号是dict方法的括号,第二层小括号是代表一个字典,第三层小括号代表字典中的每个项。
当然还有一种更神奇的方法:使用zip()创建一个字典,用法如下:
dict1 = dict(zip(['4s','5','5s'],(4999,5999,6999)))print(dict1)
结果:
{'4s': 4999, '5': 5999, '5s': 6999}
我们发现使用这几种创建字典的方法得到的结果都是一样的,这种zip方法,可以将“键”和“值”分别放入两个“[]”内,然后进行字典的创建,从而可以清楚的梳理键和值内的内容。
9.2 字典的各种内置方法(BIF)
如同列表和元组一样,字典也会有很多的内置方法,所以接下来我们列举几种经常用到的BIF;
9.2.1 get()方法
我们可以想一下,如果我们创建了一个字典,并且要使用 dict[‘iPhone 4s’] 的方式得到 ‘iPhone 4s’ 所对应的值,但是如果我们在拼写“iPhone”时将其写成了“ibhone”,那这样会造成什么结果呢?我们不妨尝试一下:
dict1 = dict(zip(['iPhone 4s','iPhone 5','iPhone 5s'],(4999,5999,6999)))print(dict1['ibhone 4s'])
结果:
Traceback (most recent call last):File "test.py", line 2, in print(dict1['ibhone 4s'])KeyError: 'ibhone 4s'
很显然,直接给我们报了错误,但是这样却造成了程序的意外停止,那么我们应该怎样去让字典对我们更宽容一些,即使出现拼写错误,也不至于造成程序停止的状况呢?此时我们就需要用到get(),一个更温柔的访问字典项的方法:
dict1 = dict(zip(['iPhone 4s','iPhone 5','iPhone 5s'],(4999,5999,6999)))print(dict1.get('ibhone 4s'))print(dict1.get('iPhone 4s'))
结果:
None4999
我们发现,这个get()方法确实很温柔,即使我们出现拼写错误,它也只是小声的告诉我们:“你要的东西我们是没有的哦”,而且不会造成程序的停止运行,而且使用起来也相当方便。
9.2.2 复制字典方法copy()
copy()方法用来复制字典时非常简便,如下述代码所示:
dict1 = {'4s':'4999','5':'5999','5s':'6999'}dict2 = dict1.copy()print(dict1)print(id(dict1))print(dict2)print(id(dict2))
结果:
{'4s': '4999', '5': '5999', '5s': '6999'}4330917440{'4s': '4999', '5': '5999', '5s': '6999'}4330917504
从结果我们可以发现两个字典的内容是完全相同的,而且两个字典分别占有不同的内存空间,所以在使用copy()方法后,会为新字典分配一个新的内存空间。
9.2.3 keys()、values()、items()方法
我们上面讲到了一种访问字典的方法get(),当然接下来的keys()、values()和items()也是用来访问字典的方法,分别的作用为:keys()用来返回字典的键;values()用来返回字典的值;items()则用来返回字典的项;举一些例子:
1.keys()方法
dict1 = {'4s':'4999','5':'5999','5s':'6999'}print(dict1.keys())
结果:
dict_keys(['4s', '5', '5s'])
结果很明显,通过keys方法可以将整个字典中的所有键进行输出。
2.values()方法
dict1 = {'4s':'4999','5':'5999','5s':'6999'}print(dict1.values())
结果:
dict_values(['4999', '5999', '6999'])
同样,使用values方法可以将字典的所有值进行输出。
3.items()方法
dict1 = {'4s':'4999','5':'5999','5s':'6999'}print(dict1.items())
结果:
dict_items([('4s', '4999'), ('5', '5999'), ('5s', '6999')])
items方法则将字典的所有项进行输出(实际就是输出了整个字典)。
9.2.4 fromkeys()方法
使用fromkeys()同样可以用来创建一个新字典,但它的用法比较特殊,特殊在哪里?举这样一个例子:小明是一个超市售货员,这天老板刚刚进了一批货,需要小明将货物名称及其价格一一对应的整理出来,这本身就是一个繁琐的工作,而且小明发现“旺旺小小酥”、“旺旺仙贝”、“旺仔牛奶”等20多件商品的价格都是一样的,但是即使发现了这样一个规律,按照我们前面学习的创建字典的方法,好像还是没有什么捷径,所以此时,fromkeys()来了:
price1 = {}price1 = price1.fromkeys(('小小酥','仙贝','牛奶','薯片','巧克力'),('15元'))print(price1)
结果:
{'小小酥': '15元', '仙贝': '15元', '牛奶': '15元', '薯片': '15元', '巧克力': '15元'}
这里我们发现,我们通过fromkeys创建字典时,只需要输入相应的键,而值只输入一次,就可以达到我们想要的结果;但是这里还是需要注意一点,在使用fromkeys创建字典前,我们需要首先创建一个空字典,并且需要将fromkeys创建的字典赋值给这个空字典,如同上面的代码块一样,实际上我们是使用fromkeys更新了之前的空字典。
9.2.5 clear()、pop()、popitem()方法
在之前讲列表的时候,我们讲到了列表的增删改查,当然在字典中同样存在删除的方法;clear()用于清空整个列表:
dict1 = {'4s':'4999','5':'5999','5s':'6999'}print(dict1)dict1.clear()print(dict1)
结果:
{'4s': '4999', '5': '5999', '5s': '6999'}{}
pop()类似的方法其实我们在列表的删除中也学到了,叫做“弹出”:
dict1 = {'4s':'4999','5':'5999','5s':'6999'}print(dict1.pop('4s'))print(dict1)
结果:
4999{'5': '5999', '5s': '6999'}
通过上面的例子可以发现,pop弹出的键对应的值可以将其输出,另外在pop弹出一个键之后,字典会删除整个相关键值对。
popitem()方法和pop()大相径庭,用来弹出字典中的某个项:
dict1 = {'4s':'4999','5':'5999','5s':'6999'}print(dict1.popitem('4s'))print(dict1)
结果:
Traceback (most recent call last):File "test.py", line 3, in print(dict1.popitem('4s'))TypeError: popitem() takes no arguments (1 given)
运行之后是不是报了同样的错误?事实上,它应该是这样用的:
dict1 = {'4s':'4999','5':'5999','5s':'6999'}print(dict1.popitem())print(dict1)
结果:
('5s', '6999'){'4s': '4999', '5': '5999'}
popitem()里不需要任何的参数,它会将字典的最后一个项弹出(之前的版本是将第一项弹出)。
9.2.6 update()方法
同样在增删改查里,字典也有“改”这个方法,或者更贴切的我们称之为“更新”,update()用于更新字典,用法同样很简单:
dict1 = {'仙贝':'15','小小酥':'15','牛奶':'15'}dict1.update(牛奶='20')print(dict1)
结果:
{'仙贝': '15', '小小酥': '15', '牛奶': '20'}
这里需要注意的是:在使用update更新字典时,不管字典中的某个键是int还是string,都不需要加引号。
以上就是字典的相关用法,当然字典作为一个足够“庞大”的数据类型,他的方法远不止这些,我们可以在pycharm中按下“ctrl/command”+点击“dict”的方式来查看更多用法。