Python对象 —— Dict对象
Python中的Dict对象
散列表概述
Python中散列表采用了开放引址法,即在发生引址冲突后再次使用散列函数寻址,直到找到空的内存地址
在删除数据时,为了防止寻址链中断,采用了软删除的方法
PyDictObject
关联容器entry
PyDictObject中存储的数据为PyObject *
DictObject存储me_hash:缓冲池,防止出现重复时key在次进行hash
存储value的容器有三个状态:
- Unused:初始态,key与value都是NULL
- Active:激活态,key与value分别存储了数据
- Dummy:删除态,当数据删除时进入Dummy软删除状态

关联容器的实现
PyDictObject是一堆关联容器的集合
PyDictObject的属性:
ma_fill:内存的全部元素ma_used:激活态元素的数量ma_smalltable:初始的内存空间,大小为8ma_mask:记录PyDictObject中entry的数量ma_table:指向存储空间的地址的初始位置,当dict申请空存储空间时,ma_table会切换地址
PyDictObject的创建与维护
PyDictObject对象创建
PyDictObject中使用缓冲池
PyDictObject实例的创建过程:
ma_smalltable清空同步设置ma_table和ma_mask- 将
ma_table指向ma_smalltable并将ma_mask设置为7
PyDictObject中的元素所有
PyDictObject中有两种搜索策略,一种是lookdict,另一种是lookdict_string。其中lookdict_string是lookdict的特殊形式
lookdict的搜索策略:
- hash key找到散列冲突链表
- 采用探测函数获取链表中下一个entry
- 检查
- value相同,返回结果
- entry为unsed态,判断freeslot是否为空
- 是,返回unsed的entry
- 否,返回freeslot
插入与删除
插入元素过程存储在PyDict_SetItem方法中:
- hash搜索定位
- insertdict方法:搜索key,存在替换
me_value,不存在则插入 - 判断内存是否需要扩大
dictresize扩大内存空间
判断内存空间充足的条件
- 装载率小于等于内存空间的2/3
- 插入方法是否使用了unused或Dummy状态的entry
内存空间不足时,会扩大为Active entry存储空间的4倍
删除元素的流程:
- 搜索entry
- 修改entry状态
- 修改内存空间,调整PyDictObject对象中维护table使用情况
操作示例
- 新建dict
![]()
- 删除元素(14,14)插入元素(104, 104)
![]()
- 再次插入(14,14)
![]()
PyDictObject对象缓冲池
PyDictObject缓冲池的原理与PyListObject相同,都是存储被删除对象的存储空间,在后面创建对象时使用
本文来自博客园,作者:lwxc,转载请注明原文链接:https://www.cnblogs.com/mars-zhz/articles/17555448.html



浙公网安备 33010602011771号