字典介绍
字典
是“
键值对
”的
无序可变序列
,
字典
中的每个元素都是一个“
键值对
”,包含:“
键
对象
”和“
值对象
”.可以通过“
键对象
”实现快速获取、删除、更新对应的“
值对象
”
列表
中我们通过“下标数字”找到对应的对象.
字典
中通过“
键对象
”找到对应的“
值
对象
”.“
键
”是任意的
不可变数据
,比如:整数、浮点数、字符串、元组.但是:
列表
、
字典
、
集合
这些
可变对象
,不能作为“
键
”.并且“
键
”不可重复。
“
值”
可以是
任意的数据
,并且
可重复
一个典型的字典的定义方式:
a = {'name':'XX','age':18,'}
字典的创建
1.
我们可以通过{}、dict()来创建字典对象
2.
通过zip()创建字典对象
3.
通过 romkeys创建值为空的字典
字典元素的访问
1. 通过
[键]
获得“
值
”.若
键不存在
,则
抛出异常
。
2. 通过
get()
方法获得“
值
”.推荐使用,
优点
是:
指定键不存在
,
返回None
;也可以
设
定指定键不存在时默认返回的对象
.推荐使用get()获取“值对象”
3. 列出所有的
键值对
,
元素.items()
4. 列出所有的
键
,列出所有的
值
,
元素.keys()
元素.values()
5.
len()
键值对
的个数
6. 检测一个“
键
”是否
在字典中
字典元素添加、修改、删除
1. 给字典新增“
键值对
”.如果“
键
”已经存在,则
覆盖旧的键值对
;如果“
键
”不存在,
则新增“
键值对
”
2. 使用
update()
将新字典中所有
键值对
全部添加到旧字典对象上.如果
key
有重复,则直
接覆盖
3. 字典中元素的删除,可以使用
del()
方法;或者
clear()
删除所有
键值对
;
pop()
删除
指定
键值对
,并
返回对应的“值对象”
4.
popitem()
:
随机删除
和
返回该键值对
.字典是“无序可变序列”,因此没有第一个元
素、最后一个元素的概念;
popitem
弹出
随机
的项,因为字典并没有"最后的元素"或者其
他有关顺序的概念.若想一个接一个地移除并处理项,这个方法就非常有效(因为不用首先
获取键的列表)
序列解包
序列解包可以用于
元组、列表、字典
。序列解包可以让我们方便的对多个变量赋值
序列解包用于字典时,默认是对“
键
”进行操作; 如果需要对
键值对
操作,则需要使用
items()
;
如果需要对“
值
”进行操作,则需要使用
values()
表格数据使用字典和列表存储,并实现访问
![](https://i-blog.csdnimg.cn/blog_migrate/539784495c17b0331bcbbb44c7dc5267.png)
r1 = {"name":"高小一","age":18,"salary":30000,"city":"北京"}
r2 = {"name":"高小二","age":19,"salary":20000,"city":"上海"}
r3 = {"name":"高小五","age":20,"salary":10000,"city":"深圳"}
tb = [r1,r2,r3]
#获得第二行的人的薪资
print(tb[1].get("salary"))
#打印表中所有的的薪资
for i in range(len(tb)): # i -->0,1,2
print(tb[i].get("salary"))
#打印表的所有数据
for i in range(len(tb)):
print(tb[i].get("name"),tb[i].get("age"),tb[i].get("salary"),tb[i].get("city"))
字典核心底层原理(重要)
字典对象的
核心
是
散列表. 散列表
是一个
稀疏数组
(总是有空白元素的数组),数组的
每个单元叫做
bucket
.每个
bucket
有两部分:一个是
键对象的引用
,一个是
值对象的引
用
。
由于,所有
bucket
结构和大小一致,我们可以通过
偏移量
来
读取指定
bucket
。
将一个键值对放进字典的底层过程
1.假设字典a对象创建完后,数组长度为8:
2.我们要把”name”=”gaoqi”这个键值对放到字典对象a中,首先第一步需要计算键”name”的散列值。Python 中可以通过 hash()来计算
3. 由于数组长度为 8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即 “101”,十进制是数字 5.我们查看偏移量 5,对应的bucket是否为空.如果为空,则将键值对放进去.如果不为空,则依次取右边3位作为偏移量,即“100”,十进制是数字
4.再查看偏移量为4的
bucket
是否为空
.直到
找到为空的
bucket
将
键值对
放进去.流
程图如下:
扩容
python 会根据散列表的拥挤程度扩容。“扩容”指的是:创造更大的
数组
,将原有内容
拷贝
到
新数组
中.接近 2/3 时,数组就会扩容。
根据键查找“键值对”的底层过程
第一步,我们仍然要计算“name”对象的散列值:
第二步,和存储的底层流程算法一致,也是依次取散列值的不同位置的数字. 假设数组长度为8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即“101”,十进制是数字 5.我们查看偏移量5,对应的bucket是否为空.如果为空,则返回None.如果不为空,则将这个bucket的键对象计算对应散列值,和我们的散列值进行比较,如果相等.则将对应“值对象”返回.如果不相等,则再依次取其他几位数字,重新计算偏移量.依次取完后,仍然没有找到.则返回None.流程图如下:
用法总结:
1. 键必须可散列
数字、字符串、元组,都是可散列的。
自定义对象需要支持下面三点:
支持
hash()函数
支持通过
__eq__()
方法检测相等性
若a==b为真,则
hash(a)==hash(b)
也为真
2. 字典在内存中开销巨大,典型的空间换时间
3. 键查询速度很快
4. 往字典里面添加新建可能导致扩容,导致散列表中键的次序变化.因此,不要在遍历字 典的同时进行字典的修改