字典核心底层原理

这篇具有很好参考价值的文章主要介绍了字典核心底层原理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

字典对象的核心是散列表。散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做bucket。每个bucket有两部分:一个是键对象的引用,一个是值对象的引用。

由于,所有bucket结构和大小一致,我们可以通过偏移量来读取指定bucket。
字典核心底层原理

将一个键值对放进字典的底层过程

a = {}
a["name"]="gaoqi"

假设字典a对象创建完后,数组长度为8:

字典核心底层原理

我们要把”name”=”gaoqi”这个键值对放到字典对象a中,首先第一步需要计算键”name”的散列值。Python中可以通过hash()来计算。

>>> bin(hash("name"))
'-0b1010111101001110110101100100101'

由于数组长度为8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即“101”,十进制是数字5。我们查看偏移量5,对应的bucket是否为空。如果为空,则将键值对放进去。如果不为空,则依次取右边3位作为偏移量,即“100”,十进制是数字4。再查看偏移量为4的bucket是否为空。直到找到为空的bucket将键值对放进去。流程图如下:

字典核心底层原理

扩容

python会根据散列表的拥挤程度扩容。“扩容”指的是:创造更大的数组,将原有内容拷贝到新数组中。
接近2/3时,数组就会扩容。

根据键查找“键值对”的底层过程

明白了,一个键值对是如何存储到数组中的,根据键对象取到值对象,理解起来就简单了。

>>> a.get("name")
'tiantian'

当调用a.get(“name”),就是根据键“name”查找到“键值对”,从而找到值对象“gaoqi”。

我们仍然要首先计算“name”对象的散列值:

>>> bin(hash("name"))
'-0b1010111101001110110101100100101'

和存储的底层流程算法一致,也是依次取散列值的不同位置的数字。 假设数组长度为8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即101,十进制是数字5。我们查看偏移量5,对应的bucket是否为空。如果为空,则返回None。如果不为空,则将这个bucket的键对象计算对应散列值,和我们的散列值进行比较,如果相等。则将对应“值对象”返回。如果不相等,则再依次取其他几位数字,重新计算偏移量。依次取完后,仍然没有找到。则返回None。流程图如下:

字典核心底层原理

用法总结:文章来源地址https://www.toymoban.com/news/detail-444324.html

  1. 字典在内存中开销巨大,典型的空间换时间。
  2. 键查询速度很快
  3. 往字典里面添加新键值对可能导致扩容,导致散列表中键的次序变化。因此,不要在遍历字典的同时进行字典的修改
  4. 键必须可散列
    • 数字、字符串、元组,都是可散列的
    • 自定义对象需要支持下面三点:(面向对象章节中再展开说)
      1. 支持hash()函数
      2. 支持通过__eq__()方法检测相等性
      3. 若a==b为真,则hash(a)==hash(b)也为真

到了这里,关于字典核心底层原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flask框架-数据库查询对象转字典或列表:实现model_to_dict的功能

    使用场景: 对于一些简单的表,可以直接通过该方法将数据查询对象进行序列化操作,转成python中列表或字典结构,再展示给前端。 1、model_to_dict方法:对单个查询对象序列化 2、model_to_list方法:查询结果是list时,对多个查询对象序列化

    2024年02月12日
    浏览(40)
  • 走进Spring的世界 —— Spring底层核心原理解析(一)

    这是学习Spring的hello world。可是,这三行代码底层都做了什么,比如: 第一行代码,会构造一个ClassPathXmlApplicationContext对象,ClassPathXmlApplicationContext该如何理解,调用该构造方法除开会实例化得到一个对象,还会做哪些事情? 第二行代码,会调用ClassPathXmlApplicationContext的ge

    2024年02月07日
    浏览(55)
  • 深入剖析 Git 对象底层原理

    在我们日常使用 Git 时,通常的操作是: 在写完一段代码后,执行 git add 命令,将这段代码添加到暂存区中 然后再执行 git commit 和 git push 命令,将 本地 Git 版本库中的提交同步到服务器中的版本库中 Git 在中间做了什么,它如何存储不同的文件和内容,以及如何区分不同分支

    2024年01月20日
    浏览(47)
  • Git如何查看分支列表?具体步骤是怎样的?底层原理是什么?

    要查看 Git 中的分支列表,可以使用 git branch 命令。该命令会列出当前仓库中所有的本地分支,并在当前分支前面加上一个星号(*)以标识当前所在的分支。 具体步骤如下: 打开终端或命令行窗口,进入 Git 仓库所在的目录。 运行 git branch 命令,该命令会列出所有本地分支

    2024年02月11日
    浏览(48)
  • 【C++干货基地】面向对象核心概念 const成员函数 | 初始化列表 | explicit关键字 | 取地址重载

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 : 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活!   哈喽各位铁汁们好啊,我是博主鸽芷咕《C++干货基地》是由我的襄阳家乡零食基地有感而发,不知道各位的城市有没有这种实惠又全面的零食基地呢?C++ 本身作

    2024年04月23日
    浏览(48)
  • React18原理: React核心对象之ReactElement对象和Fiber对象

    React中的核心对象 在React应用中,有很多特定的对象或数据结构.了解这些内部的设计,可以更容易理解react运行原理 列举从react启动到渲染过程出现频率较高,影响范围较大的对象,它们贯穿整个react运行时 如 ReactElement 对象 如 Fiber 对象 其他过程的重要对象 如事件对象(位

    2024年02月19日
    浏览(35)
  • 【C++干货基地】面向对象核心概念与实践原理:拷贝构造函数的全面解读

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 : 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活!   哈喽各位铁汁们好啊,我是博主鸽芷咕《C++干货基地》是由我的襄阳家乡零食基地有感而发,不知道各位的城市有没有这种实惠又全面的零食基地呢?C++ 本身作

    2024年03月13日
    浏览(45)
  • Python 列表转字典:实现列表和字典之间的转换

    Python 列表转字典:实现列表和字典之间的转换 在 Python 中,列表(List)和字典(Dictionary)是两种常见的数据类型。列表用于存储一组有序的元素,而字典则是一组无序的键值对。有时候我们需要将一个列表转换成一个字典,或者将一个字典转换成一个列表。这种需求在实际

    2024年02月11日
    浏览(48)
  • Python -- 列表、元组、字典、集合

    目录 一、列表 1.列表介绍 1)列表的介绍 2)列表创建方式 2.列表的增删改查 1)获取列表中某个元素(查) 2)修改元素的值(改) 3)删除元素(删) 4)添加元素(增) 3.其它常用方法 1)列表常用方法 2)常用Python内置方法 二、元组 1.元组介绍 1)元组的介绍 2)元组创建

    2024年02月03日
    浏览(63)
  • 列表、元组和字典

    可以将列表当成普通的数组,它能保存任意数量任意类型的Python 对象。像字符串一样,列表也支持下标和切片操作;列表中的项目可以改变。 字符串、列表、元组都是序列。所以列表的访问可以通过下标的偏移量访问,如: 查看第三个元素: 可以认为元组是静态的列表,元

    2024年02月09日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包