概述
关联容器(比如dict,map)的设计总会极大地关注键的“搜索效率”。一般来说,关联容器的实现都会基于设计良好的数据结构。
比如C++的STL中的map基于RB-tree(红黑树,一种平衡二叉树)实现,能够提供良好的搜索效率,其时间复杂度为O(logN)。
Pyhton中的是PyDictObject对象(dict),该对象被大量的使用,所以对搜索的效率要求极其苛刻。
因此,PyDictObject没有如map一样使用平衡二叉树,而是采用了散列表,理论上,散列表能提供O(1)的搜索时间复杂度。
散列表
散列表的目的:加速键的搜索过程。
散列函数
散列函数的优劣将直接决定所实现的散列表的搜索效率的高低。
散列冲突
装载率为“已使用空间/总空间”,当装载率大于2/3时,散列冲突发生的概率就会大大增加。
解决冲突的办法:
- 拉链法(开散列法)
- 开地址法(毕散列法)
Pyhton中使用“开地址法(开放定址法)”:
当发生冲突时,Python通过一个二次探测函数计算下一个候选位置。当候选位置可用时,将待插入元素放到候选位置上;如果不可用,则再次使用二次探测函数,获得下一个候选位置,直到找到一个可用的位置。
探测序列、伪删除。
存储实现原理
参见:Python源码剖析
操作实现原理
参见:Python源码剖析