ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

字典的底层实现原理

2022-08-06 12:44:29  阅读:175  来源: 互联网

标签:hash 索引 键值 哈希 取余 原理 字典 底层


Python字典的底层实现原理

这个问题可以从三个方面来回答:

1.python字典及其特性

字典是Python的一种可变、无序容器数据结构,它的元素以键值对的形式存在,键值唯一,它的特点搜索速度很快:数据量增加10000倍,搜索时间增加不到2倍;当数据量很大的时候,字典的搜索速度要比列表快成百上千倍1。

2.哈希表

Python字典的底层实现是哈希表。什么是哈希表,简单来说就是一张带索引和存储空间的表,对于任意可哈希对象,通过哈希索引的计算公式:hash(hashable)%k(对可哈希对象进行哈希计算,然后对结果进行取余运算),可将该对象映射为0到k-1之间的某个表索引,然后在该索引所对应的空间进行变量的存储/读取等操。

哈希运算结果 取余运算结果 索引 键值对 hash(‘小王’)=2360347816510736229 2360347816510736229%3=0 0 ’小王‘:26 hash(‘大熊’)=4284897975392025871 4284897975392025871%3=1 1 ‘大熊’:28 hash(‘牛牛’)=-7069010861127204901 -7069010861127204901%3=2 2 ‘牛牛’:3

3.Python字典如何运用哈希表

我们通过描述插入,查询,删除,扩容,哈希碰撞这几个过程来解释这一切。

插入:

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

更新:

对键进行哈希和取余运算,得到一个哈希表的索引,如果该索引所对应的地址空间中健与要更新的健一致,那么就更新该健所对应的值;

查询:

对要查找的健进行哈希和取余运算,得到一个哈希表的索引,如果该索引所对应的地址空间中健与要查询的健一致,那么就将该键值对取出来;

扩容:

字典初始化的时候,会对应初始化一个有k个空间的表,等空间不够用的时候,系统就会自动扩容,这时候会对已经存在的键值对重新进行哈希取余运算(重新进行插入操作)保存到其它位置;

碰撞:

有时候对于不同的键,经过哈希取余运算之后,得到的索引值一样,这时候怎么办?这时采用公开寻址的方式,运用固定的模式将键值对插入到其它的地址空间,比如线性寻址:如果第i个位置已经被使用,我们就看看第i+1个,第i+2个,第i+3个有没有被使用…直到找到一个空间或者对空间进行扩容。2

比如:我们想存储 {’小小‘:18}这个键值对,经过哈希和取余运算之后,我们发现,其对应的索引值是0,但是0所指向的空间已经被’小王‘占用了,这就是碰撞。怎么办呢?我们看看0+1对应的所以有没有被占用,如果没有,我们就把’小小‘放在索引1所对应的地址空间中。取的时候,也按照同样的规则,进行探查。

哈希运算 取余运算 索引值 键值对 hash(‘小王’)=2360347816510736229 2360347816510736229%3=0 0 ’小王‘:26 hash(‘小小’)=-2310146166101152587 -2310146166101152587%3=0 1 ’小小‘:18 2 为啥字典比列表查找高效 假设有一栋楼,住着1000人,你有个好朋友小王,住在这栋楼,你有急事要找他,你不知道他住几楼几号房间。这时你怎么办?你找到门卫处,向门卫说,我找小王。

列表的方法:

门卫说:我们这里每一个房间住着谁都有记录,这是记录本,你自己找吧!这个记录本有1000条记录,你从第一条开始翻,一条一条往下看,终于在第177条记录的时候找到了你的朋友小王所在的房间号。

字典的方法

门卫说: 我这里有一个公式,只要你记得你的朋友的名字,就能很快的找到你朋友在几号房间。

这个公式是:hash(姓名)%1001

对你的朋友小王的名字进行hash运算,然后对得到的结果对1001进行取余操作,得到的数字就是你的朋友小王的房间号了,经过计算,你发现hash(‘小王’)%1001=177。

总结:

列表查找是按顺序一个一个遍历,当列表越大,查找所用的时间就越久

字典是通过键值直接计算得到对应的地址空间,查找一步到位

注意 1、Cython 中 哈希表的计算公式为:hash(‘hashable’)&k,其中k 为2的n次方减1,其实与hash(‘hashable’)%(k+1)的结果一致。

2、解决碰撞的方法,Python用的不是线性寻址,而是一种更为复杂的寻址模式。2

 

标签:hash,索引,键值,哈希,取余,原理,字典,底层
来源: https://www.cnblogs.com/zouzhibin/p/16556853.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有