Python字典的核心底层原理讲解
作者:Devin01213 发布时间:2022-03-26 08:31:09
字典对象的核心是散列表。散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做 bucket。每个 bucket 有两部分:一个是键对象的引用,一个是值对象的引用。所有 bucket 结构和大小一致,我们可以通过偏移量来读取指定 bucket。下面通过存储与获取数据的过程介绍字典的底层原理。
存储数据的过程
例如,我们将‘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位数字作为偏移量。
获取数据的过程
>>> 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. 往字典里面添加新建可能导致扩容,导致散列表中键的次序变化。因此,不要在遍历字典的同时进行字典的修改。
来源:https://blog.csdn.net/ym01213/article/details/86616749


猜你喜欢
- 昨天我问过这个问题怎么用ADODB.Stream来读取或写入文件,而不是用fso,不过没人回答到点上,今天搞定了.贴出来给觉得有用的朋友,希
- 圆形的绘制 :OpenCV中使用circle(img,center,radius,color,thickness=None,lineType
- 制作一个查看器可以查看豆瓣前100名电影的信息,当然这个爬取信息比较简单。所以重点放在 QThread 多线程的应用上面。QThread 子
- 现在电子商务网站的设计,正面临着一系列的挑战,其中最主要的挑战是:我们尝试建立一种用户体验,来提高用户在线购物的可能性。为了对抗网上激烈的竞
- 介绍本文主要介绍Python中迭代的基本知识和使用什么是迭代在Python中,如果给定一个list或tuple,我们可以通过for循环来遍历
- 使用go mod之后,想要在goland中有代码提示,有两种方式,一种是使用gopath下的goimport工具,另一种是使用gomod自身
- 1. 确认已经安装了NT/2000和SQL Server的最新补丁程序,不用说大家应该已经安装好了,但是我觉得最好还是在这里提醒一下。2.
- 一、分析网页1. 打开网页,在搜索框输入百度翻译并进入百度翻译网站中。F12调出开发者工具,点击Network(网络)\ Fetch/XHR
- 闭包与defer1.闭包闭包 : 一个函数与其相关的引用环境组合的一个实体,其实可以理解为面向对象中类中的属性与方法。如代码块中,函数fun
- 今天用numpy 的linalg.det()求矩阵的逆的过程中出现了一个错误:TypeError: No loop matching the
- 编辑 my.cnf或者my.ini文件,去除下面这几行代码的注释: log_slow_queries = /var/log/mysql/my
- 如下所示:colum = ['性别','年龄','M','样本类型'] +
- 背景关于 Go 语言的 Map,有两个需要注意的特性:Map 是并发读写不安全的,这是出于性能的考虑;Map 并发读写导致的错误,无法使用
- 如果你的数据量有几十万条,用户又搜索一些很通俗的词,然后要依次读最后几页重温旧梦。mysql该很悲壮的不停操作硬盘。 所以,可以试着让mys
- 本文实例讲述了php验证session无效的解决方法。分享给大家供大家参考。具体方法如下:一、问题今天在配置 apache+php环境时折腾
- 1.阈值化分割原理通过对图像的灰度直方图进行数学统计,选择一个或多个阈值将像素划分为若干类。一般情况下,当图像由灰度值相差较大的目标和背景组
- 代码:function checkall(checkNames){ var allBoxs = document.getElem
- 测试环境:先让我们熟悉下基本的sql语句,来查看下我们将要测试表的基本信息use infomation_schemaSELECT * FRO
- # vi mysqlusers.txtcreate database dataname;grant all privileges on da
- 刚才好无聊,突然想起来之前做一个课表的点子,于是百度了起来。刚开始,我是这样想的:在写微信墙的时候,用到了urllib2【两行代码抓网页】,