第3.5节 丰富的Python字典操作
一、 基本概念
Python提供一种通过名称来访问其各个值的数据结构,这种数据结构称为映射(mapping)。字典(dict)是Python中唯一的内置映射类型,其中的值不按顺序排列,而是存储在键下,键可能是数、字符串或元组。
字典由键及其相应的值组成,键可以是任何不可变的类型,这种键-值对称为项(item)。每个键与其值之间都用冒号(:)分隔,项之间用逗号分隔,而整个字典放在花括号内。空字典(没有任何项)用两个花括号表示。
字典支持一个键对应多个值。
二、 操作方法
1、 创建字典的方法
(1) 创建空字典的两种方法:
变量= dict()
变量= {}
(2) 从键-值映射对创建字典,方法:
变量={键1:值1,键2:值2,……}
如:d={‘name’: ‘ZhangSan’, ‘age’: 42}
(3) 从以元组作为元素的列表创建字典,元组包含两个元素,第一个元素是键,第二个是该键对应的字典的值,这样列表中的每个元组对就构成了字典中的键-值对,举例如下:
d = dict([(‘name’, ‘ZhangSan’), (‘age’, 42)]) # 结果:{‘name’: ‘ZhangSan’, ‘age’: 42}
(4) 从“键=值”的方式创建字典,这里的键与上面2种方法的键稍微有些不同,这里的键的可以看做变量,其组成规则与变量相同,真正存储时键变成了包含键名的字符串,而前面2种方法的键只要是任何不可修改的数据类型。
d = dict(name=‘Gumby’, age=42)#注意,这种方法是正确的,其结果就是{‘name’: ‘ZhangSan’, ‘age’: 42}
d = dict(‘name’=‘Gumby’, ‘age’=42)#这种调用方法不正确,会报表达式错误的错误
(5) 从字典创建字典,语法:
变量=dict(dict对象)
举例:d1 = dict(d)
注意,上述语句是从字典d创建字典对象d1,其键值对与d完全相同,但这是两个不同的对象,等同于浅拷贝
l1=[1,2,3,4]
l2=[‘a’,‘b’,‘c’]
d={1:l1,2:[l1,l2]} #d={1: [1, 2, 3, 4], 2: [[1, 2, 3, 4], [‘a’, ‘b’, ‘c’]]}
d1=dict(d)
d[2][1]=100 #执行后 d={1: [1, 2, 3, 4], 2: [[1, 2, 3, 4], 100]},d1的值与其相同
d1 is d #结果为False
(6) fromkeys方法:创建一个新字典,新字典包含由参数指定的对应键,值由方法调用时默认制定,如果没有指定默认值,则所有值为None。语法为:
d={}.fromkeys(列表l,默认值)
其中l列表的元素就是新字典需要的键值,默认值不指定所有键对应的值都是None,否则就是指定值
注意,调用时的{}可以用所有字典对象代替或者dict类名代替。
例子:
d1=d.fromkeys(‘age’) #d1={‘a’: None, ‘g’: None, ‘e’: None},d是一个已有定义的字典,注意这里没有显示的用列表,缺省把字符串转换成了列表
d= dict.fromkeys([‘name’,‘age’],‘空’) # d= {‘name’: ‘空’, ‘age’: ‘空’}
(7) 支持创建一键多值的方法:
格式:
d={key1:(value1,value2 …), key2:(value1,value2 …) …};
d = dict([(‘key1’, (value1,value2 …)), (’ key2’, (value1,value2 …)) … ])
也可以使用d[key].append(value)在键上增加对应的值。
但d = {‘d1’:1,‘d2’:2,‘d1’:3},将不能创建多值,同样的键只保留最后一个,结果d= {‘d1’: 3, ‘d2’: 2}
(8) 其他创建字典的样例及说明
d = {‘1’:‘string1’,[1]:‘list1’} #报错,因为[1]是列表,而列表是可变的不能作为键值
d = {‘1’:‘string1’,(1,2):‘dict1’} # 正常执行,第二个元素的键是元组
d =dict([‘name’, ‘ZhangSan’]) #报错:ValueError: dictionary update sequence element #0 has length 4; 2 is required
d =dict([‘na’, ‘Zh’]) #正常执行,结果:{‘n’: ‘a’, ‘Z’: ‘h’}
d =dict((‘na’, ‘Zh’)) #正常执行,结果:{‘n’: ‘a’, ‘Z’: ‘h’}
d =dict(‘na’, ‘Zh’)#错误,TypeError: dict expected at most 1 arguments, got 2
d=dict(‘na’) #错误ValueError: dictionary update sequence element #0 has length 1; 2 is required
从上面几行代码可以看出,dict如果不是键值对方式创建,而是直接以字符串、列表、元组作为参数,大部分情况都报错,但是2种情况会例外:
a) 上面讲的从以元组作为元素的列表创建字典,如d = dict([(‘name’, ‘ZhangSan’), (‘age’, 42)]);
b) 从以2个长度的字符串作为元素的元组或列表创建字典,如dict([‘na’, ‘Zh’])、dict((‘na’, ‘Zh’)),这种方式其实没有多少意义。
2、 字典与列表相似的操作方法。
(1) len(d)返回字典d包含的项(键?值对)数;
(2) d[key]返回与键key相关联的值,注意这里没法用索引;
(3) d[key] = v将值v关联到键key;
(4) del d[key]删除键为key的项;
(5) key in d检查字典d是否包含键为key的项;
(6) clear方法删除所有字典项;
(7) copy方法浅拷贝字典的内容给另一个字典;
(8) deepcopy深度拷贝
深度拷贝是指针对浅拷贝来说,深度拷贝复制对象及其下所有层级的数据每个层级都是复制一份,每个层级的指向对象相对复制对象都会发生变更。这样复制后复制对象及其下的元素和原对象的变更都不会相互影响。
使用深度拷贝的方法很简单,首先需要从copy模块import深度复制方法。然后直接调用该方法复制对象。
样例从d1深度复制到d2的代码如下:
Import copy
d2 = copy.deepcopy(d1)
也可以这样:
from copy import deepcopy
d2 = deepcopy(d1)
3、 字典和列表的区别
(1) 键的类型:字典中的键可以是整数,但并非必须是整数。字典中的键可以是任何不可变的类型,如浮点数(实数)、字符串或元组。
(2) 自动添加:即便是字典中原本没有的键,也可以给它赋值,这将在字典中创建一个新项。然而,如果不使用append或其他类似的方法,就不能给列表中没有的元素赋值。
(3) 成员资格:表达式key in d(其中d是一个字典)查找的是键而不是值,而表达式v in l(其中l是一个列表)查找的是值而不是索引;
(4) 相比于检查列表是否包含指定的值,检查字典是否包含指定的键的效率更高。数据结构越大,效率差距就越大。
4、 字典的其他操作方法
(1) 字典可以通过get方法访问键对应值,调用时键作为参数,返回键对应的值,如果字典没有找到对应键,则默认返回None,也可以指定默认返回值。例如d.get(‘grade’,’空’) 当找不到grade键时,返回’空’这个字符串;
(2) Items、keys、values方法:分别返回dict_items类的字典项数据、dict_keys类的字典键数据和dict_values类的字典值数据,如:
*d={‘name’:‘张三’,‘grade’:‘3年级’} #定义字典
i,k,v=d.items(),d.keys(),d.values() #将项、键、值查询的返回值分别用i、k、v指向
print(type(i),i,sep=’,i=’)#打印项的类型及值,输出:
<class ‘dict_items’>,i=dict_items([(‘name’, ‘张三’), (‘grade’, ‘3年级’)])
print(type(k),k,sep=’,k=’)#打印键的类型及值,输出:
<class ‘dict_keys’>,k=dict_keys([‘name’, ‘grade’])
print(type(v),v,sep=',v=')#打印值的类型及值,输出:
<class 'dict_values'>,v=dict_values(['张三', '3年级'])
for ii in i:print(type(ii),ii,sep=': ') #输出项的每个元素及类型:
<class 'tuple'>: ('name', '张三')
<class 'tuple'>: ('grade', '3年级')
for kk in k:print(type(kk),kk,sep=': ') #输出键的每个元素及类型:
<class 'str'>: name
<class 'str'>: grade
for vv in v:print(type(vv),vv,sep=': ')#输出值的每个元素及类型
<class 'str'>: 张三
<class 'str'>: 3年级
l=list(i) #项转换成列表[('name', '张三'), ('grade', '3年级')],键、值也可以
d1 = dict(i)#项转换成 {'name': '张三', 'grade': '3年级'},键、值不可以
d['class']='9班' #字典增加一个元素
i,k,v #输出i、k、v的值,发现都对应随字典元素的增加而增加了内容
(dict_items([('name', '张三'), ('grade', '3年级'), ('class', '9班')]), dict_keys(['name', 'grade', 'class']), dict_values(['张三', '3年级', '9班']))*
dict_items、dict_keys和dict_values类属于一种名为字典视图的特殊类型,其数据都是字典本身的数据,这些调用相关方法后返回的视图与字典关联,当字典变化时这些前面用变量指向的返回值也会跟随变化。这三种类型都支持用for…in的方法访问其中的元素,dict_items的每个元素是个元组,可以通过list、dict、tuple方法转换为列表、字典和元组,而dict_keys和dict_values需要根据具体数据判断其每个元素的类型,能转换为列表和元组,但不能转换为字典。
(3) pop:方法pop可用于返回与指定键对应的值,并将该键-值对从字典中删除。例如:
d={‘name’: ‘张三’, ‘grade’: ‘3年级’, ‘class’: ‘9班’, 100: ‘a’}
d.pop(100) #返回‘a’,d= {‘name’: ‘张三’, ‘grade’: ‘3年级’, ‘class’: ‘9班’}
(4) popitem:方法popitem随机地弹出一个字典项,并从字典中删除该项
d.popitem() #返回(‘class’, ‘9班’),意味着该键值对从字典中删除,字典变为{‘name’: ‘张三’, ‘grade’: ‘3年级’}
(5) setdefault :方法setdefault有2个参数,第一个是键,第二个是一个缺省值,当字典中指定键存在时返回对应的值,否则在字典中新增该键,并以缺省值为该键对应的值,相当于增加了一个字典项。如:
d.setdefault(‘class’, ‘9班’) #d={‘name’: ‘张三’, ‘grade’: ‘3年级’, ‘class’: ‘9班’}
(6) update方法update使用一个字典中的项来更新另一个字典。对于通过参数提供的字典,将其项添加到当前字典中。如果当前字典包含键相同的项,就替换它。如执行如下三条指令:
d1 = {‘name’: ‘张三’, ‘grade’: ‘3年级’}
d2 = {‘name’: ‘李四’, ‘class’: ‘9班’}
d2.update(d1)
执行后d2= {‘name’: ‘张三’, ‘class’: ‘9班’, ‘grade’: ‘3年级’}
本节详细介绍了字典的概念及其操作方法,字典类型还是使用比较多的,请大家多练习后掌握相关知识。
老猿Python系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。该系列文章同步发表于:
http://blog.sina.com.cn/learnpython
http://laoyuanpython.lofter.com/
https://me.csdn.net/LaoYuanPython
由于csdn对技术文章的支持度最好,推荐大家访问csdn。欢迎大家批评指正,谢谢大家关注!