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 爬虫出现403禁止访问错误详解
Mar 11 Python
python中cPickle类使用方法详解
Aug 27 Python
python学习——内置函数、数据结构、标准库的技巧(推荐)
Apr 18 Python
Python3.5 + sklearn利用SVM自动识别字母验证码方法示例
May 10 Python
Python配置虚拟环境图文步骤
May 20 Python
Numpy的简单用法小结
Aug 28 Python
Python 3.6 中使用pdfminer解析pdf文件的实现
Sep 25 Python
python自动化实现登录获取图片验证码功能
Nov 20 Python
Flask 上传自定义头像的实例详解
Jan 09 Python
Python中url标签使用知识点总结
Jan 16 Python
Python切割图片成九宫格的示例代码
Mar 10 Python
python之随机数函数的实现示例
Dec 30 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
jq的get传参数在utf-8中乱码问题的解决php版
2008/07/23 PHP
PHP读取ACCESS数据到MYSQL的代码
2011/05/11 PHP
php小经验:解析preg_match与preg_match_all 函数
2013/06/29 PHP
PHP实现HTTP断点续传的方法
2015/06/17 PHP
浅谈PHP中静态方法和非静态方法的相互调用
2016/10/04 PHP
PHP实现向关联数组指定的Key之前插入元素的方法
2017/06/06 PHP
Laravel 5+ .env环境配置文件详解
2020/04/06 PHP
JavaScript 三种创建对象的方法
2009/10/16 Javascript
jQuery选择没有colspan属性的td的代码
2010/07/06 Javascript
根据对象的某一属性进行排序的js代码(如:name,age)
2010/08/10 Javascript
js实现在页面上弹出蒙板技巧简单实用
2013/04/16 Javascript
JS 加入收藏夹的代码(主流浏览器通用)
2013/05/13 Javascript
jQuery实现密保互斥问题解决方案
2013/08/16 Javascript
jquery.ajax之beforeSend方法使用介绍
2014/12/08 Javascript
一个字符串中出现次数最多的字符 统计这个次数【实现代码】
2016/04/29 Javascript
Angular动态添加、删除输入框并计算值实例代码
2017/03/29 Javascript
d3.js入门教程之数据绑定详解
2017/04/28 Javascript
把vue-router和express项目部署到服务器的方法
2018/02/21 Javascript
vue百度地图 + 定位的详解
2019/05/13 Javascript
基于Express框架使用POST传递Form数据
2019/08/10 Javascript
Vue 实现简易多行滚动&quot;弹幕&quot;效果
2020/01/02 Javascript
Python中input和raw_input的一点区别
2014/10/21 Python
python单例模式实例分析
2015/04/08 Python
Python实现获取系统临时目录及临时文件的方法示例
2019/06/26 Python
python线程安全及多进程多线程实现方法详解
2019/09/27 Python
Python计算指定日期是今年的第几天(三种方法)
2020/03/26 Python
解决pytorch多GPU训练保存的模型,在单GPU环境下加载出错问题
2020/06/23 Python
pytorch判断是否cuda 判断变量类型方式
2020/06/23 Python
基于tf.shape(tensor)和tensor.shape()的区别说明
2020/06/30 Python
python 获取字典键值对的实现
2020/11/12 Python
Python将QQ聊天记录生成词云的示例代码
2021/02/10 Python
毕业生的求职信范文分享
2013/12/04 职场文书
团日活动总结书
2014/05/08 职场文书
公司口号大全
2014/06/11 职场文书
物理学专业求职信
2014/07/04 职场文书
2016学校先进集体事迹材料
2016/02/29 职场文书