欢迎来到 安卓源码空间!
安卓源码空间

                               python中字典的底层是怎么实现的



【python】python中字典的底层是怎么实现的





一、相关概念


python字典的底层实现的是哈希表。调用python内置的哈希函数,将键(key)作为参数进行转换(哈希运算+取余运算),得到一个唯一的地址(地址的索引),然后将值(value)存放到对应的地址中(给相同的键赋值会直接覆盖原值,因为相同的键转换后的地址时一样的)


哈希表(Hash Table,又称为散列表)是一种线性表的存储结构。由一个直接寻址表 T (假设大小为m) 和一个哈希函数 h(k) 组成。对于任意可哈希对象,

通过哈希函数(一般先进行哈希计算,然后对结果进行取余运算),将该对象映射为寻址表的索引 [0,1,2,…m-1],然后在该索引所对应的空间 T[0,1,2,…,m-1] 

进行变量的存储/读取等操作。如下图所示。


二、哈希表

用顺序表存储数据


存储键值对时,通过哈希函数计算出键对应的索引,将值存到索引对应的数据区中
获取数据时,通过哈希函数计算出键对应的索引,将该索引对应的数据取出来


在这里插入图片描述


注:键(Key)必须是可哈希的,即,通过哈希函数可为此键计算出唯一地址。


对于 Python 来说,变量,列表、字典、集合这些都是可变的,所以都不能做为键(Key)来使用。因为元组里边可以存放列表这类可变元素,所以如果实在想拿元组

当字典的键(Key),那必须对元组做限制:元组中只包括像数字和字符串这样的不可变元素时,才可以作为字典中有效的键(Key)。另外还需要注意的一点是,

Python 的哈希算法对相同的值计算得到的结果是一样的,也就是说 12315 和 12315.0 的值相同,他们被认为是相同的键(Key)。


三、Python中字典的操作


插入: 对键进行哈希和取余运算,得到一个哈希表的索引,如果该索引所对应的表地址空间为空,将键值对存入该地址空间;


查询/更新: 对键进行哈希和取余运算,得到一个哈希表的索引,如果该索引所对应的地址空间中健与要查询/更新的健一致,那么就将该键值对取出来 / 更新该键所对应的值;
扩容: 字典初始化的时候,会对应初始化一个有k个空间的表,等空间不够用的时候,系统就会自动扩容,这时候会对已经存在的键值对 重新进行哈希取余运算

(重新进行插入操作)保存到其它位置;


四、哈希冲突


对于任何哈希函数,都会出现两个不同的元素映射到同一个位置上的情况,这种情况称为哈希冲突


在这里插入图片描述


五、解决哈希冲突——开链法


哈希表的每一个位置都连接一个链表,当发生冲突时,冲突的元素会被加到该位置的链表的最后


在这里插入图片描述


在这里插入图片描述


六、解决哈希冲突——开放寻址法


如果哈希函数得到的位置i已经有数据了,那么就往后探查新的位置来存储这个值


线性探测:如果i有数据了,则探测i+1,i+2…以此类推,直到找到空的位置


1、存储值的过程


a、key=apple,cat,dog,hello,通过哈希函数映射之后得到的值都为2
b、现有一个字典dic={‘apple’:1,‘cat’:2,‘dog’:3},存储数据,
c、原索引为2的位置没有存储数据,此时将apple的值1存储到这个
d、接着cat寻址到索引为2的位置,发现这个位置已经有值了,会继续往后探测,依次类推


在这里插入图片描述


2、获取值的过程


a、获取dic[‘dog’]的时候,先到索引为2的位置去获取


b、获取不到继续向后探测


3、删除值得过程


dic.remove(‘cat’)


a、给每一个节点定义一个状态


未使用


已使用


已删除


在这里插入图片描述


七、开链法和开放寻址法的区别


开链法:


优点:删除节点比较容易,数据量比较大使用开链法
缺点:使用空间比较大


开放寻址法:


删除节点不能真正的把节点删掉,给每一个节点定义一个状态,数据量比较小使用开放寻址法
缺点:


a、使用开放寻址法,那么顺序表总归会有一天会填满
b、一般为了保证插入和查找的效率,哈希表一般在元素数量在容量的2/3时,就会进行扩容
c、扩容之后,计算的哈希函数也会随之变化,那么里面的数据存储的顺序也会变化


八、总结



在这里插入图片描述



————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
                             原文链接:https://blog.csdn.net/YZL40514131/article/details/125349175

copyright@ 2020-2028  安卓源码空间网版权所有   

备案号:豫ICP备2023034476号-1号