字典类型是Python中最常用的数据类型之一,它是一个键值对的集合,字典通过键来索引,关联到相对的值,理论上它的查询复杂度是O (1):
在在在d={“a”: 1、“b”: 2} 在在在d ' c '=3 在在在d {“a”: 1、“b”: 2,“c”: 3}
在字符串的实现原理文章中,曾经出现过字典对象用于实习生操作,那么字典的内部结构是怎样的呢? PyDictObject对象就是dict的内部实现。
哈希表(也叫散列表),根据关键值对(键值)而直接进行访问的数据结构,它通过把键和值映射到表中一个位置来访问记录,这种查询速度非常快,更新也快。而这个映射函数叫做哈希函数,存放值的数组叫做哈希表,哈希函数的实现方式决定了哈希表的搜索效率。具体操作过程是:
1。数据添加:把键通过哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将价值存储在以该数字为下标的数组空间里。
2。数据查询:再次使用哈希函数将钥匙转换为对应的数组下标,并定位到数组的位置获取价值。
但是,对关键进行散列的时候,不同的关键可能哈希出来的结果是一样的,尤其是数据量增多的时候,这个问题叫做哈希冲突。如果解决这种冲突情况呢?通常的做法有两种,一种是链接法,另一种是开放寻址法,Python选择后者。
开放寻址法中,所有的元素都存放在散列表里,当产生哈希冲突时,通过一个探测函数计算出下一个候选位置,如果下一个获选位置还是有冲突,那么不断通过探测函数往下找,直到找个一个空槽来存放待插入元素。
字典中的一个键-值键值对元素称为条目(也叫做槽),对应到Python内部是PyDictEntry, PyDictObject就是PyDictEntry的集合.PyDictEntry的定义是:
typedef struct {/* me_key缓存的散列码。注意,哈希码C多头。 *我们必须使用Py_ssize_t而不是因为dict_popitem()的滥用 * me_hash举行搜索的手指。 */Py_ssize_t me_hash; PyObject * me_key; PyObject * me_value; }PyDictEntry;
me_hash用于缓存me_key的哈希值,防止每次查询时都要计算哈希值,输入有三种状态。
1。未使用:me_key==me_value=https://www.yisu.com/zixun/=空
未使用的是条目的初始状态,键和值都为NULL。插入元素时,未使用的状态转换成活跃状态。这是me_key为零的唯一情况。
2。活动:me_key !=NULL和me_key !=假且me_value !=NULL
插入元素后,入口就成了活跃的状态,这是me_value唯一不为零的情况,删除元素时活跃状态刻转换成假状态。
3。假:me_key==假且me_value=https://www.yisu.com/zixun/=空
此处的虚拟对象实际上一个PyStringObject对象,仅作为指示标志.Dummy状态的元素可以在插入元素的时候将它变成活跃的状态,但它不可能再变成未使用的状态。
为什么条目有虚状态呢?这是因为采用开放寻址法中,遇到哈希冲突时会找到下一个合适的位置,例如某元素经过哈希计算应该插入到一处,但是此时一处有元素的,通过探测函数计算得到下一个位置B,仍然有元素,直到找到位置C为止,此时ABC构成了探测链,查找元素时如果散列值相同,那么也是顺着这条探测链不断往后找,当删除探测链中的某个元素时,比如B,如果直接把B从哈希表中移除,即变成未使用的状态,那么C就不可能再找到了,因为交流之间出现了断裂的现象,正是如此才出现了第三种状态——假,假是一种类似的伪删除方式,保证探测链的连续性。
PyDictObject就是PyDictEntry对象的集合,PyDictObject的结构是:
typedef struct _dictobject PyDictObject; struct _dictobject { PyObject_HEAD Py_ssize_t ma_fill;+ #假*//* #活跃 Py_ssize_t ma_used;*//* #活跃/*表包含ma_mask + 1插槽,这是2的幂。 *我们存储大小的面具而不是因为面具 *经常需要的。 */Py_ssize_t ma_mask;/* ma_table指向ma_smalltable对于小表、其他 *额外分配的内存。ma_table从来不是零!这条规则 *可以节省重复运行时在主力null-tests getitem和 * setitem调用。 */PyDictEntry * ma_table; PyDictEntry * (* ma_lookup) (PyDictObject *议员PyObject *键,长散列); PyDictEntry ma_smalltable [PyDict_MINSIZE];Python字典对象实现原理详解