2021-09-10 python字典dict的相关知识

2021.9.10 dict的相关知识(累计更新)

一、 dict的内部原理

1. 哈希表

python
dict的内部数据结构是哈希表,哈希表其实是一个稀疏数组(总是有空白元素的数组成为稀疏数组)。它通过把关键码值(key-value)映射到表中的一个位置来访问记录,查找的速度十分快,理论上的世界复杂度是O(1)。因为哈希表的本质是数组,因此它在地址上是连续的,数组中每一个元素称为一个箱子(bin)或者表元(bucket),箱子中放键值对。

2. 哈希函数

哈希函数也称为散列函数,是hash表的映射函数。它可以将任意长度的输入变换为固定长度的输出。该输出值就是哈希值/散列值,即元素在哈希表中的存储位置。但是很难找到一个不产生冲突的哈希函数,所以我们只能选择恰当的哈希函数,使冲突尽可能少的产生。常用的哈希函数有:MD4、MD5、SHA1(安全散列算法)。

解决哈希冲突的方法有

  • 开放定址法:
    H i = ( H ( K e y ) + d i ) M o d m H_i=(H(Key)+d_i)Mod m Hi=(H(Key)+di)Modm,其中m是散列表的长度,d是一个序列,根据序列不同,可分为:线性探测再散列、平方探测再散列随机探测再散列.
    对应的d分别为d=[1,2,3,4,…,s], d=[ 1 2 , − 1 2 , 2 2 , − 2 2 , . . . . , s 2 , − s 2 1^2,-1^2,2^2,-2^2,....,s^2,-s^2 12,12,22,22,....,s2,s2], d为伪随机数列。
  • 链地址法
    链地址法也称为拉链法,将产生冲突的值以链表的形式连起来,采用它的优势是,处理冲突很简单,没有堆积现象。其次拉链法中的链表节点,是动态申请的。所以很适合表长不确定的情况。

3. python的dict原理

这里有一个好的参考资料
链接中的文章出现了一个例子:
在这里插入图片描述
例子分析如下:

  • 在这里例子中有两个函数很关键:hash函数和eq函数。HashTester的字典中只有一个元素是因为两个对象具有完全一样的key值和hash值。而HashTester的字典中有两个元素是因为没有重写_eq__方法,导致两者的键key的不一样的,尽管两者具有一样的hash值。

总结相关知识:

  • 同一个key对应的地址应该相同。因此只有不可变数据类型才可以做为key,而list不可变数据类型就不可以作为key。一个对象的hash值是使用其函数__hash__计算的,可变数据类型没有该函数。
a=  {}
#错误,因为list可变  list is unhashable 
a[[1,3]]="g"
# 正确,因为tuple不可变
a[(1,3)]="g"

在这里插入图片描述

  • python中的两个函数很重要,hash函数和eq函数。其中eq用于判断两个对象是否相同,而hash是计算对象的hash值。关于自定义类型中的eq和hash的相关知识见链接(这部分内容我还没有完全理解)

二. dict和list、dict和set

1.dict和list的关系

假设我们要在一本字典中查找一个汉字,在list中查找相当于从字典第一页开始翻,而dict相当于先根据偏旁部首等找到该字对应的页码,然后一下就翻到了。dict就是根据key来作为索引得到value存储的位置的

2.set和dict的关系

set和dict类似,也有一组key的集合,但不存储value。由于key不能重复,所有在set中没有重复的key。更多set的例子见 set的知识合集。

三. dict的函数

还没写呢

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值