You need to enable JavaScript to run this app. CPython字典行为:为何hash相同的-1/-2未像True/1那样合并键?
优惠活动
大模型
产品
解决方案
定价
更多

CPython字典行为:为何hash相同的-1/-2未像True/1那样合并键?

CPython 字典同哈希键不覆盖的根本原因

特殊哈希值的由来

观察到的hash(-1)与hash(-2)返回值相同,是CPython针对整数类型哈希实现的历史遗留特性:
CPython内部的字典结构中,会用哈希值-1标记空槽位(代表该位置从未存入有效键值对)。为了避免某个整数计算出的真实哈希值恰好等于-1,和空槽标记发生冲突,代码中做了特殊硬编码:只要待计算的整数原本的哈希结果是-1,就强制把哈希返回值改成-2。而-2本身的原生哈希结果恰好就是-2,最终才出现两个不同整数哈希值完全撞车的现象。

字典的双流程设计:定位靠哈希,判重靠等值

大家对字典行为的常见认知误区,本质是把“键的存储定位流程”和“键的等值判定流程”混在了一起:

  • 存储定位流程:字典计算某个键应该存入哪个槽位时,确实完全依托哈希值完成——通过哈希值对字典的槽位总数取模,得到键的初始存储位置,这部分逻辑完全不涉及键的实际值比较。
  • 键的等值判定流程:当多个键的哈希值完全相同、被定位到同一个槽位附近时,才会触发后续的等值判断逻辑,判定这些键是不是同一个:
    • 如果两个键的等值判断(通过==运算符判断)返回True,才会判定为同一个键,触发原有键值对的覆盖逻辑。
    • 如果两个键的等值判断返回False,哪怕哈希值完全一致,也会作为独立的键存储在同位置的冲突链表中,完全不会触发覆盖。

两类观察结果的对比

对比两种同哈希场景,就能直观看到逻辑差异:

  • True和1的场景:二者不仅哈希值完全相同,且由于bool是int的子类,True == 1的判断结果为True,完全满足覆盖触发的等值条件,因此最终会出现键值覆盖。
  • -1和-2的场景:虽然二者哈希值都是-2,但-1 == -2的判断结果为False,不满足等值判定的覆盖条件,因此会作为两个独立键正常存储。

设计逻辑依据

这套流程完全符合Python哈希协议的官方约定:两个判定相等的对象必须拥有相同的哈希值,但拥有相同哈希值的两个对象,不要求一定是相等的。
哈希值本质只是用来快速缩小查找范围的索引手段,从来不是判断两个对象是否等价的核心依据;等值判断才是决定两个对象能否作为同一个字典键的最终标准。

内容的提问来源于stack exchange,提问作者user459872

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.13 11:45:05