python dict底层实现_dict实现原理和哈希表

dict底层实现

在Python中,字典是依靠散列表或说哈希表(Hash Table)进行实现的,使用开放地址法解决冲突。所以其查找的时间复杂度会是O(1),下文会具体讲解哈希表的工作原理和解决冲突时的具体方法。

也就是说,字典也是一个数组,但数组的索引是键经过哈希函数处理后得到的散列值。哈希函数的目的是使键均匀地分布在数组中,并且可以在内存中以O(1)的时间复杂度进行寻址,从而实现快速查找和修改。哈希表中哈希函数的设计困难在于将数据均匀分布在哈希表中,从而尽量减少哈希碰撞和冲突。由于不同的键可能具有相同的哈希值,即可能出现冲突,高级的哈希函数能够使冲突数目最小化。

通常情况下建立哈希表的具体过程如下:

数据添加:把key通过哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。

数据查询:再次使用哈希函数将key转换为对应的数组下标,并定位到数组的位置获取value

哈希函数就是一个映射,因此哈希函数的设定很灵活,只要使得任何关键字由此所得的哈希函数值都落在表长允许的范围之内即可。本质上看哈希函数不可能做成一个一对一的映射关系,其本质是一个多对一的映射,这也就引出了下面一个概念–哈希冲突或者说哈希碰撞。哈希碰撞是不可避免的,但是一个好的哈希函数的设计需要尽量避免哈希碰撞。

Python2中使用使用开放地址法解决冲突。

CPython使用伪随机探测(pseudo-random probing)的散列表(hash table)作为字典的底层数据结构。由于这个实现细节,只有可哈希的对象才能作为字典的键

哈希表

哈希表是key-value类型的数据结构,通过关键码值直接进行访问。通过散列函数进行键和数组的下标映射从而决定该键值应该放在哪个位置,哈希表可以理解为一个键值需要按一定规则存放的数组,而哈希函数就是这个规则。此处提出几个专业名词后面会一一进行介绍。

哈希函数

装填因子

冲突

1.哈希表产生的原因假设我们存在一个简单的键值对结构,键-员工号,值-是否在岗。现在需要这样一个功能,输入员工号,返回该员工是否在岗,理想的方法是创建一个长度为Max(员工号)的数组,数组下标就是员工号,数组中的值用0和1对是否在岗进行区分,这样只需要O(1)的时间复杂度就可以完成操作,但是扩展性不强,存在以下问题。

假设新进员工的员工号比Max(员工号)还要大,这就需要重新申请数组进行迁移操作。

假设一种极端的情况,存在两个员工,员工号分别是1和100000000001,这样子的话按照先前的设计思路,是会浪费很大的存储空间的。

上面两点,第一点是因为数组的固定申请大小的属性所决定,而第二点就是引入哈希表的原因,会不会存在一个方法,让一个大员工号变小而而且没有标记,哈希函数便产生,假设此处的哈希规则是除3取模,则员工1得到的哈希值是1,员工100000000001得到的哈希值是

这样的话按照设计思路,只需要一个大小为2的数组便可以覆盖了,这就是哈希思想。

算法中时间和空间是不能兼得的,哈希表就是一种用合理的时间消耗去减少大量空间消耗的操作,这取决于具体的功能要求。

2. 哈希函数

上面的例子中哈希函数的设计很随意,但是从这个例子中我们也可以得到信息:

哈希函数就是一个映射,因此哈希函数的设定很灵活,只要使得任何关键字由此所得的哈希函数值都落在表长允许的范围之内即可;

并不是所有的输入都只对应唯一一个输出,也就是哈希函数不可能做成一个一对一的映射关系,其本质是一个多对一的映射,这也就引出了下面一个概念–冲突。

3. 冲突

只要不是一对一的映射关系,冲突就必然会发生,还是上面的极端例子,这时新加了一个员工号为2的员工,先不考虑我们的数组大小已经定为2了,按照之前的哈希函数,工号为2的员工哈希值也是2,这与100000000001的员工一样了,这就是一个冲突,针对不同的解决思路,提出三个不同的解决方法。

4.冲突解决方法

4.1 开放地址

开放地址的意思是除了哈希函数得出的地址可用,当出现冲突的时候其他的地址也一样可用,常见的开放地址思想的方法有线性探测再散列,二次探测再散列,这些方法都是在第一选择被占用的情况下的解决方法。

4.2 再哈希法

这个方法是按顺序规定多个哈希函数,每次查询的时候按顺序调用哈希函数,调用到第一个为空的时候返回不存在,调用到此键的时候返回其值。

4.3 链地址法

将所有关键字哈希值相同的记录都存在同一线性链表中,这样不需要占用其他的哈希地址,相同的哈希值在一条链表上,按顺序遍历就可以找到。

4.4公共溢出区

其基本思想是:所有关键字和基本表中关键字为相同哈希值的记录,不管他们由哈希函数得到的哈希地址是什么,一旦发生冲突,都填入溢出表。

5.装填因子α

一般情况下,处理冲突方法相同的哈希表,其平均查找长度依赖于哈希表的装填因子。哈希表的装填因子定义为表中填入的记录数和哈希表长度的壁纸,也就是标志着哈希表的装满程度。直观看来,α越小,发生冲突的可能性就越小,反之越大。一般0.75比较合适,涉及数学推导

原文:https://blog.csdn.net/shouting3901/article/details/80468735

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/542433.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网际控制报文协议icmp_网络中的ICMP(Internet控制消息协议)

网际控制报文协议icmpICMP(Internet控制消息协议)简介 (Introduction to ICMP (Internet Control Message Protocol)) IP (Internet Protocol) is a network layer protocol. The responsibility of delivering data (Logical Addressing) to any network is done by the IP (I…

谈色

最近很苦恼,像是到了男人的生理期,或者说是类似动物的发情期,见到露长腿的女人总喜欢看。 其实我是并不喜欢这样盯着看,或许是男人的本色,十个男人九个色的本性,总是会不自觉的去偷看,更有甚者还…

linux系统怎样写单片机程序,单片机知识是Linux驱动开发的基础之一以及如何学单片机...

这是arm裸机1期加强版第1课第2、3节课程的wiki文字版。为什么没前途也要学习单片机?因为它是个很好的入口。学习单片机可以让我们抛开复杂的软件结构,先掌握硬件操作,如:看原理图、芯片手册、写程序操作寄存器等。在上一节视频里&…

python教程循环语句_Python教程:关于Python 循环语句

Python 循环语句本章节将向大家介绍Python的循环语句,程序在一般情况下是按顺序执行的。编程语言提供了各种控制结构,允许更复杂的执行路径。循环语句允许我们执行一个语句或语句组多次,下面是在大多数编程语言中的循环语句的一般形式&#x…

math.pow int_Java Math类static int min(int i1,int i2)与示例

math.pow int数学类静态int min(int i1,int i2) (Math Class static int min(int i1 , int i2) ) This method is available in java.lang package. 此方法在java.lang包中可用。 This method is used to return the minimum one of both the given arguments or in…

bat 批处理 常用命令和乱码问题

为什么80%的码农都做不了架构师?>>> rem echo off ECHO OFF XCOPY E:\test.bat D:\ IF ERRORLEVEL 1 ECHO 文件拷贝Failure IF ERRORLEVEL 0 ECHO 文件拷贝Success :start set /p first"1记事本,2远程:" if %first% LEQ 2 (IF %first% …

SuperMap iServer发布的ArcGIS REST 地图服务如何通过ArcGIS API加载

作者:yx 文章目录 一、发布服务二、代码加载三、结果展示 一、发布服务 SuperMap iServer支持将地图发布为ArcGIS REST地图服务,您可以在发布服务时直接勾选ArcGIS REST地图服务,如下图所示: 也可以在已发布的地图服务中&#x…

c语言中的运算符及其含义_按位运算符及其在C语言中与Example一起使用

c语言中的运算符及其含义1)&(按位与) (1) & (bitwise AND)) It does AND on every bit of two numbers. The result of AND is 1 only if both bits are 1. 它对两个数字的每一位进行“与”运算。 仅当两个位均为1时,AND的结果才为1。 Example: 例&…

能上网的Linux系统,那一款linux能上网

zhoushao12 于 2009-02-24 19:13:07发表:linux日常使用中,最重要的就是网络(本人觉得)特别时ubuntu .但是现在电信偏偏搞什么账号加密要用互联星空软件才可以拨号,更可恶的是这X软件只有Windws版的!! 使得在linux下拨号上网变得十分麻烦!在网上找了很久终于找到解决方法!!下面拿…

李洪强经典面试题37

1.写一个NSString类的实现 (id)initWithCString:(c*****t char *)nullTerminatedCString encoding:(NSStringEncoding)encoding; (id) stringWithCString: (c*****t char*)nullTerminatedCString encoding: (NSStringEncoding)encoding { NSString *obj; obj [self al…

new file会创建文件吗_Rust 文件系统处理之文件读写 Rust 实践指南

Rust 中,文件读写处理简单而高效。代码也很紧凑,容易阅读。我们从读取文件的字符串行、避免读取写入同一文件、使用内存映射随机访问文件这三个文件处理中的典型案例来了解一下。文件处理场景大家都很熟悉,因此闲言少叙,直接看代码…

python 打印文件名_在Python中打印文件名,关闭状态和文件模式

python 打印文件名Prerequisite: Opening, closing a file/open(), close() functions in Python 先决条件: 在Python中打开,关闭文件/ open(),close()函数 1)文件名(file_object.name) (1) File name (file_object.name)) To get the file …

linux搭建直播步骤,Linux 下 nginx + rtmp 搭建直播服务

简单粗暴直接上步骤吧:注 : 以下示例使用的是nginx(版本1.15.3) rtmp(版本1.2.1)下载nginx和rtmp模块下载nginx解压​ tar xvf nginx-1.15.3.tar.gz下载nginx rtmp模块解压​ tar xvf v1.2.1进入nginx目录​ cd nginx-1.15.3执行:#--add-module 指向rtmp模块目录,ad…

【Maven学习笔记(二)】Maven的安装与配置

为什么80%的码农都做不了架构师&#xff1f;>>> 1、默认本地仓库路径 C:\Users\97449\.m2\repository 2、修改本地仓库路径 打开D:\apache-maven\conf\settings.xml <?xml version"1.0" encoding"UTF-8"?><!-- Licensed to the Apa…

npm 全局安装vuecli报错_cnn explainer本地使用--被npm坑惨

最近在知乎上面看到&#xff0c;看到一个cnn解释器&#xff0c;把每个步揍都很清楚的展示了出来&#xff0c;我想自己搞来玩玩。第一次使用npm&#xff0c;很多地方不会&#xff0c;第一步&#xff1a;先在网页上下载下来cnn_explainer&#xff0c;然后解压在没有中文路径的文件…

Python程序从给定的N个数字中找到最大倍数

Here, we will be framing code for finding the maximum multiple of a number x from a given set of a number (set of 5 numbers in this program). 在这里&#xff0c;我们将使用成帧代码&#xff0c; 从给定的一组数字(此程序中的5个数字组成的集合)中找到x的最大倍数 。…

ubuntu linux本地源,如何制作UbuntuLinux操作系统的本地源?

最简单制作本地源的方法&#xff1a;在packs文件夹中有如下两种类型的包&#xff1a;一种是。deb包(全部的依赖包和软件包)&#xff0c;另一种是Packages。gz着重介绍一下第二个类型的包&#xff1a;在这个包中包含了必需的软件包列表和依赖信息。这个包是后生成的&#xff0c;…

openmpi安装_Intel Parallel Studio XE 2019安装设置

1.Intel Parallel Studio XE 2019简介Intel Parallel Studio XE 是Intel在单独一款软件开发套件中整合了英特尔公司业界领先的 C/C 和 Fortran 编译器、性能和MPI并行库、错误检查、代码健壮和性能分析的工具&#xff0c;有助于大幅提升应用程序性能&#xff0c;同时提高代码质…

Python | 在列表中指定索引处添加元素的程序

Given a list and we have to add an element at specified index in Python. 给定一个列表&#xff0c;我们必须在Python中的指定索引处添加一个元素。 list.appened() Method is used to append/add an element at the end of the list. But, if we want to add an element …