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 相关文章推荐
用pywin32实现windows模拟鼠标及键盘动作
Apr 22 Python
python之wxPython菜单使用详解
Sep 28 Python
Python中逗号的三种作用实例分析
Jun 08 Python
在Django中管理Users和Permissions以及Groups的方法
Jul 23 Python
利用matplotlib+numpy绘制多种绘图的方法实例
May 03 Python
Python实现的微信好友数据分析功能示例
Jun 21 Python
tensorflow saver 保存和恢复指定 tensor的实例讲解
Jul 26 Python
Python 实现子类获取父类的类成员方法
Jan 11 Python
python实现一个函数版的名片管理系统过程解析
Aug 27 Python
详解anaconda安装步骤
Nov 23 Python
python - timeit 时间模块
Apr 06 Python
Pytorch中使用ImageFolder读取数据集时忽略特定文件
Mar 23 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知识收集
2012/08/20 PHP
php中mysql连接方式PDO使用详解
2015/02/25 PHP
php动态添加url查询参数的方法
2015/04/14 PHP
php实现在服务器端调整图片大小的方法
2015/06/16 PHP
php简单防盗链实现方法
2015/07/29 PHP
PHP+Session防止表单重复提交的解决方法
2018/04/09 PHP
PHP simplexml_import_dom()函数讲解
2019/02/03 PHP
JS+CSS制作DIV层可(最小化/拖拽/排序)功能实现代码
2013/02/25 Javascript
JS 去前后空格大全(IE9亲测)
2013/07/15 Javascript
使用JavaScript实现Java的List功能(实例讲解)
2013/11/07 Javascript
jquery实现简单合拢与展开网页面板的方法
2015/09/01 Javascript
js实现新浪微博首页效果
2015/10/16 Javascript
信息页文内画中画广告js实现代码(文中加载广告方式)
2016/01/03 Javascript
js删除Array数组中指定元素的两种方法
2016/08/03 Javascript
React Native实现简单的登录功能(推荐)
2016/09/19 Javascript
Vue.js列表渲染绑定jQuery插件的正确姿势
2017/06/29 jQuery
详解vue 模拟后台数据(加载本地json文件)调试
2017/08/25 Javascript
初探JavaScript 面向对象(推荐)
2017/09/03 Javascript
Vue结合SignalR实现前后端实时消息同步
2017/09/19 Javascript
基于casperjs和resemble.js实现一个像素对比服务详解
2018/01/10 Javascript
Vue配合iView实现省市二级联动的示例代码
2018/07/27 Javascript
ant design的table组件实现全选功能以及自定义分页
2020/11/17 Javascript
[01:18:45]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第三场2月1日
2021/03/11 DOTA
优化Python代码使其加快作用域内的查找
2015/03/30 Python
Python的Django中将文件上传至七牛云存储的代码分享
2016/06/03 Python
Python表示矩阵的方法分析
2017/05/26 Python
PyQt 线程类 QThread使用详解
2017/07/16 Python
基于python select.select模块通信的实例讲解
2017/09/21 Python
django开发post接口简单案例,获取参数值的方法
2018/12/11 Python
python爬虫获取百度首页内容教学
2018/12/23 Python
Tensorflow之梯度裁剪的实现示例
2020/03/08 Python
医院节能减排方案
2014/06/13 职场文书
小班上学期幼儿评语
2014/12/30 职场文书
师德师风主题教育活动总结
2015/05/07 职场文书
律师催款函范文
2015/06/24 职场文书
Go标准容器之Ring的使用说明
2021/05/05 Golang