Python字典的核心底层原理讲解


Posted in Python onJanuary 24, 2019

字典对象的核心是散列表。散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做 bucket。每个 bucket 有两部分:一个是键对象的引用,一个是值对象的引用。所有 bucket 结构和大小一致,我们可以通过偏移量来读取指定 bucket。下面通过存储与获取数据的过程介绍字典的底层原理。

Python字典的核心底层原理讲解

存储数据的过程

例如,我们将‘name' = ‘张三' 这个键值对存储到字典map中,假设数组长度为8,可以用3位二进制表示。

>>> map = {}
>>> map
{}
>>> map['name'] = '张三'

1、计算name的散列值。

>>> bin(hash('name'))
'0b101011100000110111101000101010100010011010110010100101001000110'

2、用散列值的最右边 3 位数字作为偏移量,即“110”,十进制是数字 6。我们查看偏移量 6,对应的 bucket 是否为空。如果为空,则将键值对放进去。如果不为空,则依次取右移 3 位作为偏移量,即“000”,十进制是数字0,循环此过程,直到找到为空的 bucket 将键值对放进去。python 会根据散列表的拥挤程度扩容。“扩容”指的是:创造更大的数组,将原有内容拷贝到新数组中。接近 2/3 时,数组就会扩容。扩容后,偏移量的数字个数增加,如数组长度扩容到16时,可以用最右边4位数字作为偏移量。

Python字典的核心底层原理讲解

获取数据的过程

>>> map.get('name')
'张三'

1、计算name的散列值

2、用最右边 3 位数字作为偏移量,即“110”,十进制是数字6。查看偏移量 6,对应的 bucket 是否为空。如果为空,则返回 None。如果不为空,则将这个 bucket 的键对象计算对应散列值,和我们的散列值进行比较,如果相等,则将对应“值对象”返回;如果不相等,则再依次取其他几位数字,重新计算偏移量。循环此过程。

小结:

1.键必须可散列,如数字、元组、字符串;自定义对象需要满足支持hash、支持通过__eq__()方法检测相等性、若 a==b 为真,则 hash(a)==hash(b)也为真。

>>> b = [1,2] //List不可散列
>>> bin(hash(b))
Traceback (most recent call last):
 File "<pyshell#90>", line 1, in <module>
  bin(hash(b))
TypeError: unhashable type: 'list'

2. 字典在内存中开销巨大,典型的空间换时间;

3. 键查询速度很快;

4. 往字典里面添加新建可能导致扩容,导致散列表中键的次序变化。因此,不要在遍历字典的同时进行字典的修改。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。如果你想了解更多相关内容请查看下面相关链接

Python 相关文章推荐
Python常见数据结构详解
Jul 24 Python
几个提升Python运行效率的方法之间的对比
Apr 03 Python
简单介绍Python中的JSON模块
Apr 08 Python
python中的代码编码格式转换问题
Jun 10 Python
Python解析最简单的验证码
Jan 07 Python
python使用正则表达式的search()函数实现指定位置搜索功能
Nov 10 Python
使用python list 查找所有匹配元素的位置实例
Jun 11 Python
python pillow模块使用方法详解
Aug 30 Python
Python3.7下安装pyqt5的方法步骤(图文)
May 12 Python
Python flask框架如何显示图像到web页面
Jun 03 Python
Python迭代器协议及for循环工作机制详解
Jul 14 Python
Django2.1.7 查询数据返回json格式的实现
Dec 29 Python
使用PIL(Python-Imaging)反转图像的颜色方法
Jan 24 #Python
Python3实现取图片中特定的像素替换指定的颜色示例
Jan 24 #Python
python 实现图片旋转 上下左右 180度旋转的示例
Jan 24 #Python
Python对象与引用的介绍
Jan 24 #Python
selenium+python自动化测试之多窗口切换
Jan 23 #Python
python 去除二维数组/二维列表中的重复行方法
Jan 23 #Python
selenium+python自动化测试之鼠标和键盘事件
Jan 23 #Python
You might like
php桌面中心(四) 数据显示
2007/03/11 PHP
PHP高手需要要掌握的知识点
2014/08/21 PHP
PHP正则替换函数preg_replace和preg_replace_callback使用总结
2014/09/22 PHP
CentOS 安装 PHP5.5+Redis+XDebug+Nginx+MySQL全纪录
2015/03/25 PHP
PHP时间函数使用详解
2019/03/21 PHP
AJAX异步从优酷专辑中采集所有视频及信息(JavaScript代码)
2010/11/20 Javascript
用jQuery中的ajax分页实现代码
2011/09/20 Javascript
js获取height和width的方法说明
2013/01/06 Javascript
JQuery的Ajax请求实现局部刷新的简单实例
2014/02/11 Javascript
node.js中的fs.mkdir方法使用说明
2014/12/17 Javascript
JavaScript中pop()方法的使用教程
2015/06/09 Javascript
使用contextMenu插件实现Bootstrap table弹出右键菜单
2017/02/20 Javascript
vue实现简单表格组件实例详解
2017/04/16 Javascript
Vue.js用法详解
2017/11/13 Javascript
浅析java线程中断的办法
2018/07/29 Javascript
nodejs npm错误Error:UNKNOWN:unknown error,mkdir 'D:\Develop\nodejs\node_global'at Error
2019/03/02 NodeJs
Vue2.x通用条件搜索组件的封装及应用详解
2019/05/28 Javascript
ES6新增的数组知识实例小结
2020/05/23 Javascript
[02:35]DOTA2超级联赛专访XB 难忘一年九冠称王
2013/06/20 DOTA
[51:43]OG vs LGD 2018国际邀请赛淘汰赛BO3 第五场 8.26
2018/08/30 DOTA
老生常谈Python序列化和反序列化
2017/06/28 Python
python 获取当天每个准点时间戳的实例
2018/05/22 Python
python-pyinstaller、打包后获取路径的实例
2019/06/10 Python
Selenium+Python 自动化操控登录界面实例(有简单验证码图片校验)
2019/06/28 Python
python绘图模块matplotlib示例详解
2019/07/26 Python
Python 求数组局部最大值的实例
2019/11/26 Python
Python类中self参数用法详解
2020/02/13 Python
Python爬取梨视频的示例
2021/01/29 Python
使用html5 canvas 画时钟代码实例分享
2015/11/11 HTML / CSS
HTML5实现直播间评论滚动效果的代码
2020/05/27 HTML / CSS
澳大利亚实惠时尚女装商店:Katies
2019/06/16 全球购物
西式结婚主持词
2014/03/14 职场文书
小学兴趣小组活动总结
2014/07/07 职场文书
Apache压力测试工具的安装使用
2021/03/31 Servers
Nginx已编译的nginx-添加新模块
2021/04/01 Servers
Nginx缓存设置案例详解
2021/09/15 Servers