Python字典和集合的内部实现
1. 哈希表(Hash tables)
在Python中,字典是通过哈希表实现的。也就是说,字典是一个数组,而数组的索引是经过哈希函数处理后得到的。哈希函数的目的是使键均匀地分布在数组中。由于不同的键可能具有相同的哈希值,即可能出现冲突,高级的哈希函数能够使冲突数目最小化。Python中并不包含这样高级的哈希函数,几个重要(用于处理字符串和整数)的哈希函数通常情况下均是常规的类型:
>>> map(hash, (0, 1, 2, 3))
[0, 1, 2, 3]
>>> map(hash, ("namea", "nameb", "namec", "named"))
[-1658398457, -1658398460, -1658398459, -1658398462]
如果在Python中运行 hash('a') ,后台将执行 string_hash()函数,然后返回 12416037344 (这里我们假设采用的是64位的平台)。
如果用长度为 x 的数组存储键/值对,则我们需要用值为 x-1 的掩码计算槽(slot,存储键/值对的单元)在数组中的索引。这可使计算索引的过程变得非常迅速。字典结构调整长度的机制(以下会详细介绍)会使找到空槽的概率很高,也就意味着在多数情况下只需要进行简单的计算。假如字典中所用数组的长度是 8 ,那么键'a'的索引为:hash('a') & 7 = 0,同理'b'的索引为 3 ,'c'的索引为 2 , 而'z'的索引与'b'相同,也为 3 ,这就出现了冲突。

可以看出,Python的哈希函数在键彼此连续的时候表现得很理想,这主要是考虑到通常情况下处理的都是这类形式的数据。然而,一旦我们添加了键'z'就会出现冲突,因为这个键值并不毗邻其他键,且相距较远。当然,我们也可以用索引为键的哈希值的链表来存储键/值对,但会增加查找元素的时间,时间复杂度也不再是 O(1) 了。下一节将介绍Python的字典解决冲突所采用的方法。
2. dict与set的实现原理
dict与set实现原理是一样的,都是将实际的值放到list中。唯一不同的在于hash函数操作的对象,对于dict,hash函数操作的是其key,而对于set是直接操作的它的元素,假设操作内容为x,其作为因变量,放入hash函数,通过运算后取list的余数,转化为一个list的下标,此下标位置对于set而言用来放其本身,而对于dict则是创建了两个list,一个list该下表放此key,另一个list中该下标方对应的value。
其中,我们把实现set的方式叫做Hash Set,实现dict的方式叫做Hash Map/Table(注:map指的就是通过key来寻找value的过程)
3.hash碰撞及其解决方法
(1)开放寻址法(Open addressing)
开放寻址法是一种用探测手段处理冲突的方法。在上述键'z'冲突的例子中,索引 3 在数组中已经被占用了,因而需要探寻一个当前未被使用的索引。增加和搜寻键/值对需要的时间均为 O(1)。


(2)拉链法
原理图如下,其实就是将发生有冲突的元素放到同一位置,然后通过“指针“来串联起来

参考文献:
【2】python 下的数据结构与算法---8:哈希一下【dict与set的实现】
Python字典和集合的内部实现的更多相关文章
- 流畅的python 字典和集合
介绍 dict 类型不但在各种程序里广泛使用,它也是 Python 语言的基石.模块的命名空间.实例的属性和函数的关键字参数中都可以看到字典的身影.跟它有关的内置函数都在 __builtins__._ ...
- Python字典和集合
Python字典操作与遍历: 1.http://www.cnblogs.com/rubylouvre/archive/2011/06/19/2084739.html 2.http://5iqiong. ...
- day3学python 字典+列表集合+文件读取
字典+列表集合+文件读取 字典示例 ************************ 各地食品的三级菜单************************* 1.使用字典嵌套字典 2.采用死循环思路 3 ...
- Python 字典dict 集合set
字典dict Python内置字典,通过key-value进行存储,字典是无序的,拓展hash names = ['Michael', 'Bob', 'Tracy'] scores = [95, 75 ...
- Python 字典和集合基于哈希表实现
哈希表作为基础数据结构我不多说,有兴趣的可以百度,或者等我出一篇博客来细谈哈希表.我这里就简单讲讲:哈希表不过就是一个定长数组,元素找位置,遇到哈希冲突则利用 hash 算法解决找另一个位置,如果数组 ...
- python 字典元组集合字符串
s1 = ''hello, world!'' s2 = '\n\hello, world!\\n' print(s1, s2, end='') s1 = '\141\142\143\x61\x62\x ...
- 转:Python字典与集合操作总结
转自:http://blog.csdn.net/business122/article/details/7537014 一.创建字典 方法①: >>> dict1 = {} > ...
- Python字典、集合之高山流水
字典dict字典是由大括号{键:值}组成.字典是无序的.字典的键必须是不可变数据类型.不能使用列表作为键,但可以使用元祖作为字典的键.例如: dict_ = {"test":&qu ...
- python字典与集合操作
字典操作 字典一种key - value 的数据类型,使用就像我们上学用的字典,通过笔划.字母来查对应页的详细内容. 语法: info = { 's1': "jack", 's3' ...
随机推荐
- for循环 例子
<script type="text/javascript"> //循环 for循环 //循环操作某一个功能(执行某段代码) //四要素 1.循环初始值 2.循环条件 ...
- Django----From组件
Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 1.创建Form类 from django.f ...
- 洛谷P1316 丢瓶盖【二分】【贪心】
题目:https://www.luogu.org/problemnew/show/P1316 题意: 给定a个点的坐标(在一条直线上),现在要选b个点,问这b个点的最近距离的最大值是多少. 思路: 感 ...
- .NET Core开发日志——Controller
在理清路由的工作流程后,接下来需要考虑的,是MVC框架如何生成Controller以及它的生成时机. 根据以前ASP.NET MVC的经验,Controller应该是由一个ControllerFact ...
- 用Python下载美国国家气候数据中心(NCDC)的气候数据
美国国家气候数据中心的官网地址是https://www.ncdc.noaa.gov/ 气候数据的下载地址是: 长格式:ftp://ftp.ncdc.noaa.gov/pub/data/noaa/,这种 ...
- [No0000EA]C# 可空类型(Nullable)
C# 可空类型(Nullable) C# 提供了一个特殊的数据类型,nullable 类型(可空类型),可空类型可以表示其基础值类型正常范围内的值,再加上一个 null 值. 例如,Nullable& ...
- windows共享文件分析
·小结: 1.win+r,\\ip 弹出登录框,输入Guest,密码空登录:前置检查来宾账户状态: 2.net use 查看当前已经连接到的主机 实践: C:\Users\sas>net u ...
- wpf(布局与Canvas )
WPF的布局有控件都在System.Windows.Controls.Panel这个基类下面,常见的布局控件: . canvas: Canvas是最基本的面板,它不会自动调整内部元素的排列及大小,它仅 ...
- [daily][archlinux][game] 几个linux下还不错的游戏
春节在家放松, 装了几个游戏在archlinux上,玩起来还不错. 假期结束开工了, 玩的时间也会比较少,准备删掉, 记录如下: 1. 0ad 即时战略类, 类似于冷兵器时代的红警. 画面还不错, 可 ...
- 《mongoDB》基本操作-创建/更新/删除文档
一:基本操作 - db; 当前选择的集合(等于数据库名) > db demo - use db_name; 选择你要操作的集合 > use demo switched to db dem ...