深入理解Python虚拟机中字典(dict)的实现原理及源码剖析

yizhihongxing

深入理解Python虚拟机中字典(dict)的实现原理及源码剖析

Python中,字典(dict)是一种非常常用的数据结构,其实现原理是一种哈希表。

哈希表是什么

哈希表(Hash Table),也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构。哈希表通过把关键码值映射到哈希表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做哈希函数(Hash Function),存放记录的数组叫做哈希表(Hash Table)。

Python中的哈希表

Python 3.x 中的哈希表是由一个 dictobject 类来实现的,它定义在文件 Objects/dictobject.c 中,我们可以通过阅读这个文件来了解哈希表的实现细节。

实现细节

存储结构

哈希表主要由三个部分组成:

  1. 哈希表本身的结构体(PyDictObject),其成员变量包含:

    a. 哈希表的大小(size):表示哈希表中存储的键值对个数。

    b. 元素个数(n_used):表示哈希表中已经使用的大小。

    c. 哈希表的表头(table):实际存储元素的数组,它的长度必须是 2 的幂次方。

  2. 哈希函数: Python使用一种稳定的哈希函数,取模运算的方式让哈希值在0~table长度之间。

  3. 碰撞处理

    a. 开放寻址:即采用线性探测法,发生冲突后,在哈希表中向后寻找下一个可用的位置。

    b. 链接法:如果位置已经被占用,则把该位置的链表指针向后移动,挂接在后面。

Python采用的是链接法,即哈希表数组中的每一个元素都是一个指针,指向一个链表。当冲突发生时,它会把新元素插入到链表的头部。

插入元素

当我们使用字典时,如果需要新增一个键值对就会发生插入操作,具体插入操作包括以下几个步骤:

  1. 计算键的哈希值。

  2. 使用哈希函数计算键的索引值。

  3. 检查这个索引的位置是否已经有元素。

  4. 如果这个位置没有元素,就直接将键值对插入到这个位置。

  5. 如果这个位置有元素,可能是跟这个位置对应的链表的第一个位置发生了冲突,我们需要遍历链表,找到要插入的键是否已经存在。

  6. 如果键已经存在,就用新的值覆盖旧的值。

  7. 如果键不存在,则在链表的头部插入一个新的节点。

查找元素

当我们使用字典时,如果需要查找一个键是否存在,具体查找操作包括以下几个步骤:

  1. 计算键的哈希值。

  2. 使用哈希函数计算键的索引值。

  3. 检查这个索引的位置是否已经有元素。

  4. 如果这个位置没有元素,就表明键不存在。

  5. 如果这个位置有元素,可能是跟这个位置对应的链表的第一个位置发生了冲突,我们需要遍历链表,找到要查找的键是否存在。

  6. 如果键存在,就返回它的值。

  7. 如果键不存在,则返回一个 KeyError 异常。

示例说明

下面我们通过两个示例来演示哈希表的实现细节。

示例1:添加元素

例如,我们有一个空的字典:

d = {}

我们要向字典中添加键值对 "hello": 1,那么具体流程如下:

  1. 计算 "hello" 的哈希值。

  2. 使用哈希函数计算 "hello" 的索引值。

  3. 检查索引值所在的数组位置是否有元素。

  4. 因为这个位置没有元素,所以将键值对 "hello": 1 插入到这个数组位置。

  5. 现在字典中已经有一个元素了,所以将 n_used 加 1。

示例2:查找元素

例如,我们有一个字典:

d = {"hello": 1, "world": 2}

我们要查找键 "world" 的值,那么具体流程如下:

  1. 计算 "world" 的哈希值。

  2. 使用哈希函数计算 "world" 的索引值。

  3. 检查索引值所在的数组位置是否有元素。

  4. 因为这个位置有元素,所以需要在这个元素对应的链表上查找 "world"。

  5. 找到 "world" 元素并返回它的值2。

这就是 Python 哈希表的工作原理,希望对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解Python虚拟机中字典(dict)的实现原理及源码剖析 - Python技术站

(0)
上一篇 2023年5月13日
下一篇 2023年5月13日

相关文章

  • python实现的重启关机程序实例

    下面我将为您详细讲解如何实现“python实现的重启关机程序实例”。 1. 实现重启功能 首先,我们可以使用os.system函数来实现机器重启功能。具体步骤如下: 导入os模块 import os 调用os.system函数,执行restart命令 os.system("shutdown -r") 上述代码将会执行机器的重启操作。可以将…

    python 2023年5月23日
    00
  • 使用 python 请求获取 403

    【问题标题】:Getting 403 with python requests使用 python 请求获取 403 【发布时间】:2023-04-05 16:17:01 【问题描述】: 我有一个刮板,到今天为止,它已经运行了 18 个月,没有出现任何问题。现在我从 htlv.org 收到 403 响应,似乎无法解决问题。我的代码在下面,所以答案不是通常只添加…

    Python开发 2023年4月5日
    00
  • python-opencv如何读取图片及尺寸修改

    下面是详细的攻略: 1. 安装OpenCV 首先,我们需要安装OpenCV模块,可以通过以下命令进行安装: pip install opencv-python 安装完成后,就可以开始使用OpenCV模块。 2. 读取图片 要读取图片,可以使用OpenCV中的imread()函数。该函数的语法如下: img = cv2.imread(path, flag) 其…

    python 2023年5月18日
    00
  • python pandas实现excel转为html格式的方法

    下面是python pandas实现excel转为html格式的方法的完整实例教程。 1. 安装依赖库 首先需要安装 pandas 库,可以通过 pip 来安装: pip install pandas 2. 导入库并读取数据 接下来需要导入相应的库并读取数据,将 Excel 文件读入 pandas 的 dataframe 中,这里以一个名为 sheet1 的…

    python 2023年5月13日
    00
  • Python 重新缩放数据

    【问题标题】:Python Rescale DataPython 重新缩放数据 【发布时间】:2023-04-04 19:46:01 【问题描述】: 我在以下代码中收到此错误。我收到的错误没有给我任何地址的线索。请帮忙。 错误:TypeError: ‘ 代码: from pandas import read_csv from numpy import set…

    Python开发 2023年4月6日
    00
  • python 字典和列表嵌套用法详解

    Python字典和列表嵌套用法详解 在Python中,我们可以使用字典(dict)和列表(list)来存储数据。有时候,我们需要将字典和列表组合起来使用,这就是字典和列表的嵌套用法。本文将详细讲解中字典和列表的嵌套用法,并提供两个示例说明。 字典和列表的嵌套 字典和列表的嵌套是指一个字典中,我们可以使用列表作为值,或者在一个列表中,我们可以使用字典作为元素。…

    python 2023年5月13日
    00
  • Winform控件优化Paint事件实现圆角组件及提取绘制圆角的方法

    Winform控件优化Paint事件实现圆角组件及提取绘制圆角的方法 在Winform应用程序中,我们经常需要使用到圆角控件来美化界面。但是Winform本身并不提供这样的控件,因此我们需要自己实现。本文将介绍如何通过优化Paint事件实现圆角组件,并提供两个示例说明。 1. Paint事件 Paint事件是控件绘制的重要事件之一,当控件需要进行绘制时,便会…

    python 2023年6月13日
    00
  • 对python中基于tcp协议的通信(数据传输)实例讲解

    下面是详细讲解“对python中基于tcp协议的通信(数据传输)实例讲解”的完整攻略。 一、TCP协议简介 TCP协议是TCP/IP协议族中的一种重要协议,它是一种可靠的、面向连接的、基于字节流的传输协议。TCP协议在网络通信中广泛应用,比如HTTP、FTP、SMTP等广泛应用的协议都是基于TCP协议的。 二、Python中的TCP通信 Python标准库中…

    python 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部