pythondict
实现使用哈希值来基于键稀疏存储值并避免该存储中的冲突。它以 的结果hash()
作为起点,它不是确定的位置。
因此,尽管hash(4)
返回4
,但底层 C 结构中的确切“位置”也基于已经存在的其他键以及当前表的大小。例如,python 哈希表会根据需要调整大小(添加项目)。
由于 dict 没有顺序,这不是你需要担心的事情,也不需要影响。如果您需要在 dict 中排序,请改用collections.OrderedDict()
实现,它会单独跟踪排序。
python哈希表实现细节
您可能想了解哈希表在Wikipedia上的工作原理;Python 使用开放寻址来实现它。
当在表中选择一个槽时,哈希值(一个整数)和当前表大小的模被取,因此在一个大小为 32 的表上,所以 key 45
,哈希值45
最初将存储在槽 14 中。
如果发生冲突(槽 14 中已经存储了其他内容,并且不是整数45
),则槽值会受到干扰,直到找到空槽或找到相同的键。扰动是通过以下公式完成的:
perturb = slot = hash
while slot_is_full and item_in_slot_is_not_equal_to_key:
slot = (5*slot) + 1 + perturb
perturb >>= 5
因此,当发生冲突时,会以越来越小的步长选择另一个槽,直到它扫描整个表。请注意,如果需要,表格已经调整大小以腾出空间。
为了使其正常工作,自定义类型既需要一个__hash__()
方法,也需要实现__eq__()
来确定两个实例是否代表同一个键。匹配哈希值是不够的。为了让dict
实现考虑两个实例来表示完全相同的键,它们的哈希值必须匹配,并且它们必须为==
相等运算符返回 True。这样的对象被认为是可散列的。
(对于 Python 2.x,实现__cmp__()
钩子而不是实现__eq__()
; 在 Python 3 中已删除对此的支持)。