概述

关联容器(比如dict,map)的设计总会极大地关注键的“搜索效率”。一般来说,关联容器的实现都会基于设计良好的数据结构。

比如C++的STL中的map基于RB-tree(红黑树,一种平衡二叉树)实现,能够提供良好的搜索效率,其时间复杂度为O(logN)。

Pyhton中的是PyDictObject对象(dict),该对象被大量的使用,所以对搜索的效率要求极其苛刻。

因此,PyDictObject没有如map一样使用平衡二叉树,而是采用了散列表,理论上,散列表能提供O(1)的搜索时间复杂度。

散列表

散列表的目的:加速键的搜索过程。

散列函数

散列函数的优劣将直接决定所实现的散列表的搜索效率的高低。

散列冲突

装载率为“已使用空间/总空间”,当装载率大于2/3时,散列冲突发生的概率就会大大增加。

解决冲突的办法:

  • 拉链法(开散列法)
  • 开地址法(毕散列法)

Pyhton中使用“开地址法(开放定址法)”:

当发生冲突时,Python通过一个二次探测函数计算下一个候选位置。当候选位置可用时,将待插入元素放到候选位置上;如果不可用,则再次使用二次探测函数,获得下一个候选位置,直到找到一个可用的位置。

探测序列、伪删除。

存储实现原理

参见:Python源码剖析

操作实现原理

参见:Python源码剖析

Reference

python源码分析:dict对象的实现