我知道在python中,字典是通过散列键并在数组中存储指针(键值对)来实现的,索引由散列决定。
但是键值对本身是如何存储的?它们是否存储在一起(即存储在连续的位置)?它们是存储为元组还是指针数组,一个指向键,另一个指向值?或者它完全是另一回事?
谷歌搜索已经发现了许多关于散列和开放寻址等的解释,但没有解决这个问题。
答案 0 :(得分:1)
粗略地说有一个函数,我们称之为F
,它在一个值数组中计算索引F(h)
。因此,值将存储为数组,并将其查找为F(h)
。它大致说"的原因是对于不同的对象,哈希的计算方式不同。例如,对于指针,它是p>>3
;而对于字符串,哈希是字符串所有字节的摘要。
如果您想查看C代码,请搜索lookdict_index
或者只查看CPython源代码中的dictobject.c文件。如果您习惯于阅读C代码,那么它非常易读。
编辑1: 从Python 3.6.1的注释中包括/ dictobject.h:
/* If ma_values is NULL, the table is "combined": keys and values
are stored in ma_keys.
If ma_values is not NULL, the table is splitted:
keys are stored in ma_keys and values are stored in ma_values */
来自dictobject的解释。:
/*
The DictObject can be in one of two forms.
Either:
A combined table:
ma_values == NULL, dk_refcnt == 1.
Values are stored in the me_value field of the PyDictKeysObject.
Or:
A split table:
ma_values != NULL, dk_refcnt >= 1
Values are stored in the ma_values array.
Only string (unicode) keys are allowed.
All dicts sharing same key must have same insertion order.
....
*/
这些值要么存储为一个字符串数组,它遵循一组"关键对象"。或者每个值的指针都存储在me_value
的{{1}}中。密钥存储在PyDictKeyEntry
的{{1}}字段中。键数组实际上是me_key
结构数组。
作为参考,PyDictKeyEntry
定义为:
PyDictKeyEntry
要查看的相关文件:Python的源代码中的Objects / dict-common.h,Objects / dictobject.c和Include / dictobject.h。
Objects / dictobject.c在文件开头的注释中有大量的内容,用于解释整个方案和历史背景。