十二.Python中的字典dict(键值对)以及存储原理

字典是"键值对"的无序可变序列,字典中的每个元素都是一个"键值对",包含:"键对象",和"值对象".可以通过"键对象"实现快速获取,删除,更新对应的"值对象".

列表中我们通过"下标数字"找到对应的对象,字典中通过"键对象"找到对应的"值对象"."键"是任意的不可变数据,比如:整数,浮点数,字符串,元组.但是:列表,字典,集合这些可变的对象,不能作为"键".并且"键"不可重复."值"可以是任意的数据,并且可重复.

 

一个典型的字典的定义方式:

取字典的值

 

字典的创建:

1.可以使用{},dict()来创建字典对象

a = {}

b = dict(key1=value1,key2=value2)

注:这里面的key不需要带"引起"直接就可以使用

c = dict([key1,key2],[value1,value2])

 

 

2.通过zip()创建字典对象

k = ["name","age","job"]

b = ["tangmoumou","18","student"]

d = dict(zip(k,b))

 

3.通过fromkeys创建键值为空的字典

a = dict.fromkeys('name','age','job'])

 

字典元素的访问

 

为了测试各种访稳方法,先预设一个字典兑现:

a = {"name":"唐","age":18,"job":"programmer"}

 

1.通过键获取值,若键不存在,则抛出异常

2.通过get()方法获得 "值",推荐使用

有的时候:返回具体的值,当指定键不存在时,返回None;也可以设置指定键不存在的时候默认返回的对象.推荐使用get()获取值对象

设置get的默认返回值

 

3.列出所有额键值对

a.items()

 

4.列出所有键,列出所有的值

a.keys()

a.values()

 

5.len()键值对的个数

 

6.检测一个 "键"是否在字典中

 

字典元素添加,修改和删除

 

1.给字典新增 键值对,如果键已经存在,则覆盖 旧的建制地;如果 键不存在,则新增 键值对

 

 

2.使用update()将字典中所有键值对全部添加到旧字典对象上.如果key有重复,则直接覆盖

 

 

3.字典中元素的删除,可以使用del()方法,或者clear()删除所有的键值对;pop()删除指定的键值对,并返回对应的"值对象"

4.popitem():随机删除和返回该键值对.字典是"无序可变序列",因此没有第一个元素,最后一个元素的概念:popitem弹出随机的项,因此字典并没有"最后的元素"或者其他有关熟悉怒的概念,若想一个接一个移除并处理项,这个方法就非常有效(因为不用首先获取键的列表)

 

序列解包

 

序列解包可用于元组,列表,字典.序列解包可以让我们方便的对多个变量赋值.

 

序列解包用于字典时,默认是对"键"进行操作;如果需要对键值对操作,则需要使用items();如果需要对"值"进行操作,则需要使用values();

 

s = {"name":"唐某某","age":18,"job":"student"}

 

 

 

 

 

 

字典核心底层原理(重要)

 

字典对象的核心是散列表.散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做bucket,每个bucket有两部分:一个是键对象的引用,一个是值对象的引用.

由于,所有bucket结构和大小一致,我么可以通过偏移量来指定bucket.

将一个键值对放进字典的底层过程

a={}

a["name"] = "tang"

 

当将"name"="tang"这个键值对放到字典对象a中,首先第一步要计算键"name"的散列表.Python可以使用hash()来计算.

由于数组长度为8,我们可以拿计算出的散列值,最右边3位数作为偏移量,即"010",十进制是数字2,我们查看偏移量2,对应的bucket是否为空,如果为空,则将键值放进去,如果不为空,依次取右边3位作为偏移量'101',十进制是数字5,再查看偏移量5的bucket是否为空.直到栈为空的bucket将键值放进去

 

 

根据键查找"键值对"的底层过程

一个键值对是如果存储到数组中的,根据键值对象取到值对象,理解起来就简单了

a.get("name")

当我们调用a.get("name"),就是根据键"name"查找"键值对",从而找到值"tang"

 

第一步,我们仍要计算"name"对象的散列值:

bin(hash("name"))

和存储的底层流程算法一致,也是一次取散列值不同的数字,假设数组长度为8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即"010",十进制是数字2,我们查看偏移量5,对应的bucket是否为空.如果为空则返回None.如果不为空,则将这个bucket对象的键对象计算对应的散列值,和我们的散列值进行比较,如果相等,则将对应"值对象"返回,如果不相等,则一次取其它几位数字,重新计算偏移量,依次取完后仍没有找到哦啊,则返回None.

 

用法总结:

  • 1.键必须可散列

数字,字符串,元组,都是可散列的

自定义对象需要支持下面三点;

支持hash()函数

支持通过__eq__()方法尖刺相等性

做a==b为真,则hash(a)==hash(b)也为真.

  • 2.字典在内存中开销巨大,典型的空间换时间.
  • 3.键值查询速度很快
  • 4.往字典烈面添加新键可能导致扩容,导致散列表中的键的次序发生变化.因此,不要在遍历字典的同时对字典的修改.

 

 

  • 9
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值