文章目录
字典是另一种可变容器模型,且可存储任意类型对象。
定义
字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中 。其中键值是唯一的,不能重复。值格式如下所示:
#创建方法一 直接创建
>>> dic={'zhangsan':'S001','lisi':'S002','wangwu':'S003'}
>>> dic
{'zhangsan': 'S001', 'lisi': 'S002', 'wangwu': 'S003'}
#创建方法二 利用元祖/列表
>>> dic=(['zhangsan','S001'],['lisi','S002'])
>>> dict(dic)
{'zhangsan': 'S001', 'lisi': 'S002'}
#或者用这样的方法
>>> dic=dict(name='zhangsan',age=23)
>>> dic
{'name': 'zhangsan', 'age': 23}
#创建方法三 使用fromkeys
>>> help(dict.fromkeys)
Help on built-in function fromkeys:
fromkeys(iterable, value=None, /) method of builtins.type instance
Create a new dictionary with keys from iterable and values set to value.
# 可以看到使用formkeys可以批量创建不同keys单值一样的字典,其中的迭代器可以是列表也以是元组。
>>> dic={}.fromkeys(('a','s','d'),1)
>>> dic
{'a': 1, 's': 1, 'd': 1}
>>> dic={}.fromkeys(['a','s','d'],1)
>>> dic
{'a': 1, 's': 1, 'd': 1}
操作
访问及修改
字典类型的对象是以键值对的形式存储数据的。所以,只要知道键,就能找到值。本质上就是一种映射关系。
{'a': 10, 's': 10, 'd': 10}
>>> dic['a']
10
>>> dic['a']=9
>>> dic
{'a': 9, 's': 10, 'd': 10}
长度len()
返回字典(d)中的键值对的数量。
>>> dic
{'a': 9, 's': 10, 'd': 10}
>>> len(dic)
3
查找及删除
key in d, 检查字典(d) 中是否含有键为key的项。
# 修改
>>> dic={'a': 9, 's': 10, 'd': 10}
>>> 'a' in dic
True
del d[key], 删除字典(d) 的键(key) 项(将该键值对删除) 。
# 删除指定项
>>> del dic['a']
>>> dic
{'s': 10, 'd': 10}
# 删除整个字典
>>> del dic
>>> dic
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'dic' is not defined
字符串格式化输出
关于字符串格式化输出问题在字符串一章已经涉及过,这里主要探究通过字典实现格式化字符串对目的。
>>> print("c's value is %(c)s. a's value is %(a)s" %dic)
c's value is 7. a's value is 3
字典的函数
跟前面所讲述对其他对象类似,字典也有一些函数,通过这些函数我们能够实现对字典对操作。
copy和deepcopy
在python中,“ = ” 是一种引用的复制,这一点在数字那一张也有详细从内存上讨论过,这里我们再次回顾一下:
>>> a=2
>>> b=a
>>> id(a)
140707635106656
>>> id(b)
140707635106656
由于python中的变量都是采用的引用语义,数据结构可以包含基础数据类型,导致了在python中每个变量中都存储了这个变量的地址,而不是值本身。
同样如果如果仅仅是单纯对使用 “ = ” 来复制的话,就像在列表以及数字中提及的那样,复制过来的仅仅是抵制饮用而已。
>>> dic={}.fromkeys(('asd','qwe'),1)
>>> copy_dic=dic
>>> id(dic)
1654004468616
>>> id(copy_dic)
1654004468616
这样做会有什么和后果呢?假如我们希望在复制的内容中做一些修改将结果输出,而原来对内容并不希望改变。由于使用对是地址引用,因此在改变copy_dic的时候,dic也变了。
>>> copy_dic['asd']=2
>>> dic
{'asd': 2, 'qwe': 1}
如何做到复制对是值而不是对象对引用呢? 这时候copy()大喊一声:我来了!
>>> id(dic)
1654004468616
>>> copy_dic=dic.copy()
>>> id(copy_dic)
1654004466024
>>> dic
{'asd': 2, 'qwe': 1}
>>> copy_dic
{'asd': 2, 'qwe': 1}
我们惊奇的发现,通过copy()后,复制对是值而不是地址了。可是还有一个问题:
>>> dic={'name':'zhang','learn':['math','physics','PE']}
>>> copy_dic=dic.copy()
>>> copy_dic['learn'].remove('PE')
>>> copy_dic
{'name': 'zhang', 'learn': ['math', 'physics']}
>>> dic
{'name': 'zhang', 'learn': ['math', 'physics']}
诶?woc什么鬼,难道copy()的不对吗?让我来叫id()来查查看:
>>> id(dic)
1654004468400
>>> id(copy_dic)
1654004465808
是不是更加迷惑了,别急,让我们想想问题出在哪了,首先我们通过copy()复制过来的一定是值而不是地址,对于list来说它的值就是list对引用,即虽然两个字典不是同一个地址块,但两个字典中对列表对应的是同一个列表区域。
>>> id(dic['learn'])
1654004267976
>>> id(copy_dic['learn'])
1654004267976
怎么办呢?deepcopy()这时候过来了,老哥不行了呀,换我来吧:
>>> import copy
>>> dic={'name':'zhang','learn':['math','physics','PE']}
>>> copy_dic=copy.deepcopy(dic)
>>> copy_dic['learn'].remove('PE')
>>> dic
{'name': 'zhang', 'learn': ['math', 'physics', 'PE']}
>>> copy_dic
{'name': 'zhang', 'learn': ['math', 'physics']}
关于深浅拷贝还可以参见python——赋值与深浅拷贝
clear清除
简言之,clear()的作用就是将字典内容清空。我们先看一下clear的函数说明:
Help on method_descriptor:
clear(...)
D.clear() -> None. Remove all items from D.
让我们来看一下clear的运行结果,可以发现通过使用clear()主动将字典中的内容删除掉了,当然也可以直接用“dic={}”将dic的引用转向“{}”,原来的内容没有引用则变成了垃圾,python会主动回收。当然,如果不想用了也可以直接用del删掉。
>>> dic
{'name': 'zhang', 'learn': ['math', 'physics', 'PE']}
>>> dic.clear()
>>> dic
{}
get和setdefult
get()
先让我们看一下get()的函数说明:
>>> help(dict.get)
Help on method_descriptor:
get(self, key, default=None, /)
Return the value for key if key is in the dictionary, else default.
可以看到如果key在字典中,则返回key的值,否则返回default。
>>> dic={'name':'zhang','learn':['math','physics','PE']}
>>> dic.get('name','null')
'zhang'
>>> dic.get('age','null')
'null'
dict.get()相对于dict[i]而言,没有那么严格。dict.get()可以对字典中没有存在的键返回初值或着不返回。但dict[i]则会直接报错。
setdefault()
先让我们看一下setdefult()的函数说明:
>>> help(dict.setdefault)
Help on method_descriptor:
setdefault(self, key, default=None, /)
Insert key with a value of default if key is not in the dictionary.
Return the value for key if key is in the dictionary, else default.
与get不同的是,如果key不在字典中,则插入值为default的key。如果key在字典中,则返回key的值,否则返回default。
>>> dic
{'name': 'zhang', 'learn': ['math', 'physics', 'PE']}
>>> dic.setdefault('name','null')
'zhang'
>>> dic.setdefault('age','null')
'null'
>>> dic
{'name': 'zhang', 'learn': ['math', 'physics', 'PE'], 'age': 'null'}
>>> dic.setdefault('sex')
>>> dic
{'name': 'zhang', 'learn': ['math', 'physics', 'PE'], 'age': 'null', 'sex': None}
items, keys, values
老规矩,先让我们看一下函数说明:
>>> help(dict.items)
Help on method_descriptor:
items(...)
D.items() -> a set-like object providing a view on D's items
# 一个类似于集合的对象,提供D的项目视图
我们可以使用dict.items()来遍历字典中的数据,当然如果我们直接使用list得到的是dict的键,通过dict.items()提供的视图我们可以将整个字典转化为list。
>>> dic=dict(name="wangwu",age=25)
>>> dic.items()
dict_items([('name', 'wangwu'), ('age', 25)])
>>> for i,j in dic.items():
... print(i,":",j)
name : wangwu
age : 25
>>> list(dic)
['name', 'age']
>>> list(dic.items())
[('name', 'wangwu'), ('age', 25)]
相似的keys和values提供的则分别是键和值的视图。
>>> dic.keys()
dict_keys(['name', 'age'])
>>> dic.values()
dict_values(['wangwu', 25])
pop和popitem
在list中我们有提到过pop和remove,其中list.pop(i)是删除指定索引元素,而list.remove(x)则是删除指定元素。
字典中我们也有两个类似的删除方式pop和popitem,在pop中是指删除指定键和对应的值,返回值。在popitem中则是随机删除一组键值并返回(一般是随机加载出来字典的最后一个元素)。
>>> dic
{'name': 'wangwu', 'age': 25}
# pop
>>> dic.pop("name")
'wangwu'
#popitem
>>> dic.popitem()
('age', 25)
update
首先让我们先来看一下函数说明:
>>> help(dict.update)
Help on method_descriptor:
update(...)
D.update([E, ]**F) -> None. Update D from dict/iterable E and F.
If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]
#如果E存在且有.key()方法,则执行:for k in E: D[k] = E[k]
If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v
#如果E存在且没有.key()方法,则执行:for k, v in E: D[k] = v
In either case, this is followed by: for k in F: D[k] = F[k]
可以看出首先这个函数是没有返回值的,它的作用就是更新字典。其参数是字典或者某种可以迭代的对象。
# 字典更新字典
>>> E=dict(name="wangwu")
>>> D=dict(sex=22)
# 方式一
>>> D.update(E)
>>> D
{'sex': 22, 'name': 'wangwu'}
# 方式二
>>> E=(["sex",20],["lang","python"])
>>> D.update(E)
>>> D
{'sex': 20, 'name': 'wangwu', 'lang': 'python'}
# 方式三
>>> D.update(name="zhangsan")
>>> D
{'sex': 20, 'name': 'zhangsan', 'lang': 'python'}