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

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

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

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

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

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

CPython使用伪随机探测(pseudo-random probing)的散列表(hash table)作为字典的底层数据结构。由于这个实现细节,只有可哈希的对象才能作为字典的键。字典的三个基本操作(添加元素,获取元素和删除元素)的平均事件复杂度为O(1)。

Python中所有不可变的内置类型都是可哈希的。

可变类型(如列表,字典和集合)就是不可哈希的,因此不能作为字典的键。

常见的哈希碰撞解决方法:

1 开放寻址法(open addressing)

开放寻址法中,所有的元素都存放在散列表里,当产生哈希冲突时,通过一个探测函数计算出下一个候选位置,如果下一个获选位置还是有冲突,那么不断通过探测函数往下找,直到找个一个空槽来存放待插入元素。

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

2 再哈希法

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

3 链地址法

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

4 公共溢出区

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

5 装填因子α

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

在python中一个key-value是一个entry,

entry有三种状态。

Unused: me_key == me_value == NULL

Unused是entry的初始状态,key和value都为NULL。插入元素时,Unused状态转换成Active状态。这是me_key为NULL的唯一情况。

python字典实现原理_Python字典底层实现原理详解相关推荐

  1. python解释器的工作原理_Python GIL全局解释器锁详解(深度剖析)

    通过前面的学习,我们了解了 Pyton 并发编程的特性以及什么是多线程编程.其实除此之外,Python 多线程还有一个很重要的知识点,就是本节要讲的 GIL. GIL,中文译为全局解释器锁.在讲解 G ...

  2. python defaultdict 类属性_Python collections.defaultdict模块用法详解

    Python中通过Key访问字典,当Key不存在时,会引发'KeyError'异常.为了避免这种情况的发生,可以使用collections类中的defaultdict()方法来为字典提供默认值. 语法 ...

  3. python函数参数定义_Python函数定义及参数详解

    函数定义 首先我们来创建一个函数,输出指定范围内的斐波拉契数列(Fibonacci series). #!/usr/bin/env python #coding=utf-8 ''' Created o ...

  4. python 正则式替换_python 正则表达式参数替换实例详解

    正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. re 模块使 Python ...

  5. python多进程应用场景_python使用多进程的实例详解

    python多线程适合IO密集型场景,而在CPU密集型场景,并不能充分利用多核CPU,而协程本质基于线程,同样不能充分发挥多核的优势. 针对计算密集型场景需要使用多进程,python的multipro ...

  6. python语言格式化输出_Python format()格式化输出方法详解

    原标题:Python format()格式化输出方法详解 format() 方法的语法格式如下: str.format(args) 此方法中,str 用于指定字符串的显示样式:args 用于指定要进行 ...

  7. python的socket模块_Python socket模块方法实现详解

    这篇文章主要介绍了python socket模块方法实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 socket ssh (不带防止粘包的方 ...

  8. python协程库_python中协程的详解(附示例)

    本篇文章给大家带来的内容是关于python中协程的详解(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 协程,又称微线程,纤程.英文名Coroutine 协程看上去也是子程序 ...

  9. python语法错误概述_Python 错误和异常代码详解

    程序中的错误一般被称为 Bug,无可否认,这几乎总是程序员的错... 程序员的一生,始终伴随着一件事 - 调试(错误检测.异常处理).反反复复,最可怕的是:不仅自己的要改,别人的也要改...一万头草泥 ...

  10. python中字符串乘法_python leetcode 字符串相乘实例详解

    给定两个以字符串形式表示的非负整数 num1 和  num2 ,返回  num1 和  num2 的乘积,它们的乘积也表示为字符串形式. 示例 1: 输入: num1 = "2", ...

最新文章

  1. VTK:Medical之TissueLens
  2. 毕业一年的员工跳槽需要理由吗?
  3. JavaScript判断访问终端
  4. unitywebplayer 32/64 5.3版本
  5. STC 18B20温度传感器读写程序
  6. 大数据推荐系统(4)推荐算法
  7. 赛门铁克symantec 卸载需要密码解决方法
  8. ghost.py 使用实例
  9. VB DoEvents 的使用
  10. 手机迅雷打不开html,苹果手机上迅雷怎么打不开秒退
  11. 华为鸿蒙OS精品资料汇总,持续更新中
  12. Vue 合同模板_【开源】后端开发也很容易上手的前端框架模板
  13. 扁平化数组的几种方法
  14. 人脸识别行业分析报告
  15. 江南大学C语言大作业,TCPIP大作业基于TCP的网络通信编程C语言版(江南大学).doc...
  16. ACwing每日一题3565暴力 绝对值不等式 中位数思维
  17. jdk api 1.6中文版打不开
  18. 互联网行业的发展趋势和挑战
  19. mysql安装完为什么打不开,mysql安装打不开的解决方法
  20. [2018.04.17][水][日志][5][#160][虚伪的椰子树][简直丧心病狂][背景-amp;amp;gt;][请求题中福利][递归+纯模拟一只]

热门文章

  1. 如何将mac中的资料拷贝到U盘,移动硬盘
  2. python对于前端开发有用吗_python和前端开发怎么抉择?
  3. QuotedStr函数
  4. python爬虫 房天下js逆向模拟登录
  5. "北京成功故事"系列报道之四:巴伐利亚啤酒酿造师在北京
  6. python安装lda_python 安装 lda topic主题模型
  7. rides雪崩和rides穿透学习
  8. ORA-12541: TNS: 无监听程序 的解决办法
  9. win10 64bit+ qt5.12.0 + msvc2017 + libtorch(pytorch)+cuda10.1+cudnn7.6配置
  10. docker-compose文档