字典是“键值对”的无序可变序列,字典中的每个元素都是一个“键值对”,包含︰“键对象”和“值对象”。可以通过“键对象”实现快速获取、删除、更新对应的“值对象”。
字典中通过“键对象”找到对应的“值对象”。“键”是任意的不可变数据,比如∶整数、浮点数、字符串、元组。但是∶列表、字典、集合这些可变对象,不能作为“键”。并且“键”不可重复。“值”可以是任意的数据,并且可重复。
目录
一、字典的创建
①通过{}、dict()创建字典对象
②通过zip创建字典对象
③通过fromkeys创建值为None的字典对象
二、字典的访问
① 通过[]访问
②通过get()访问
③列出所有键值对
④列出所有的键,所有的值
⑤len()
⑥ in
三、字典的添加、修改和删除
①直接修改
②update()
③del(),pop(),clear()
④popitem()
四、解包
五、核心底层原理
①存储
②读取
③总结
一、字典的创建 ①通过{}、dict()创建字典对象
a={key1:value1,key2:value2} a=dict([(key1,value1),(key2,value2)]) a=dict(key1=value1,key2=value2) #貌似key1和key2默认为字符串,不能加'',不能数字开头②通过zip创建字典对象
a=dict(zip(key的列表、元组或集合,value的列表、元组或集合))③通过fromkeys创建值为None的字典对象
a=dict.fromkeys(key的列表、元组或集合)二、字典的访问 ① 通过[]访问
通过a[key]来访问对应的value,不存在则抛出异常②通过get()访问
通过get()方法获得“值”,当指定键不存在时,返回None ,也可以设定指定键不存在时默认返回的对象
a.get(key) #不存在默认返回Nonea.get(key,返回内容)③列出所有键值对
a=dict.fromkeys({1,2,3,4}) print(a.items()) #结果为:dict_items([(1, None), (2, None), (3, None), (4, None)])④列出所有的键,所有的值
键
a=dict.fromkeys({1,2,3,4})print(a.keys()) #结果为:dict_keys([1, 2, 3, 4])
值
a=dict.fromkeys({1,2,3,4})print(a.values()) #结果为:dict_values([None, None, None, None])⑤len()
返回字典的键值对数
a=dict.fromkeys({1,2,3,4})print(len(a)) #结果为:4⑥ in
判断键是否在字典中
a=dict.fromkeys({1,2,3,4}) print(1 in a) #结果为:True三、字典的添加、修改和删除 ①直接修改
如果key不存在,则会会在字典里生成新的key:value;存在则会覆盖原先的value
②update()将新字典中所有键值对全部添加到旧字典对象上,如果key有重复,则直接覆盖
a={1:2,2:3,3:4} b={1:3,4:5} a.update(b) print(a) #结果为:{1: 3, 2: 3, 3: 4, 4: 5}③del(),pop(),clear()
a={1:2,2:3,3:4}del(a[1]) #删除键值对1:2 print(a) a.pop(2) #删除键值对2:3 print(a) a.clear() #删除所有键值对 print(a) ''' 结果为: {2: 3, 3: 4} {3: 4} {} '''④popitem()
随机返回并删除字典中的最后一对键和值
a={1:2,2:3,3:4} b=a.popitem() print(b) print(a) b=a.popitem() print(b) print(a) ''' 结果为: (3, 4) {1: 2, 2: 3} (2, 3) {1: 2} '''四、解包
对键 *** 作
a={1:2,2:3,3:4} q,w,e=a print(q) print(w) print(e) ''' 结果为: 1 2 3 '''
对键值 *** 作
a={1:2,2:3,3:4} q,w,e=a.items() print(q) print(w) print(e) ''' 结果为: (1, 2) (2, 3) (3, 4) '''
对值 *** 作
a={1:2,2:3,3:4} q,w,e=a.values() print(q) print(w) print(e) ''' 结果为: 2 3 4 '''五、核心底层原理 ①存储
字典对象的核心是散列表。散列表是一个稀疏数组(总是有空白元素的数组〕,数组的每个单元叫做 bucket。每个 bucket有两部分∶一个是键对象的引用,一个是值对象的引用。由于,所有bucket结构和大小一致,我们可以通过偏移量来读取指定bucket。
先计算键对象的散列值(hash),然后根据数组的长度从右至左取二进制数换算为十进制数,若索引bucket为空,则将键值对存储进去,若为否,则依次再取散列值右侧的二进制数换算为十进制数,直到对应索引bucket为空。
Python会根据散列表的拥挤程度(接近2/3时)创造更大的数组,将原有内容拷贝到新数组中。
②读取和存储的底层流程算法一致,也是依次取散列值的不同位置的数字。根据数组的长度从右至左取二进制数换算为十进制数,查找对应的bucket 是否为空。如果为空,则返回None。如果不为空,则将这个bucket的键对象计算对应散列值,和我们的散列值进行比较,如果相等。则将对应“值对象”返回。如果不相等,则再依次取其他几位数字,重新计算偏移量。依次取完后仍然没有找到。则返回None。
③总结1.键必须可散列
(1)数字、字符串、元组,都是可散列的。
(2)自定义对象需要支持下面三点︰
①支持hash()函数
②支持通过__eq__()方法检测相等性
③若a==b为真,则hash(a)= =hash(b)也为真
2.字典在内存中开销巨大,典型的空间换时间
3.键查询速度很快
4、往字典里面添加新建可能导致扩容,导致散列表中键的次序变化。因此,不要在遍历字典的同时进行字典的修改(可以遍历字典的复制)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)