You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为含多个可比较属性的Python对象实现__hash__方法

核心问题:你当前的相等逻辑不符合等价关系要求

Python 中__eq__定义的相等关系必须是等价关系,满足三个基本条件:

  • 自反性:x == x 恒为真
  • 对称性:如果 x == y 那么 y == x
  • 传递性:如果 x == y 且 y == z,那么 x == z
    你现在设计的「a相等或b相等就视为相等」的逻辑不满足传递性,举个简单的例子:
t1 = Transaction(1, 2)
t2 = Transaction(1, 3)
t3 = Transaction(4, 3)

按照你的逻辑t1 == t2(a属性相等)、t2 == t3(b属性相等),但t1和t3的a、b都不相等,明显不满足传递性,这种情况下你不可能写出符合「相等对象哈希必须一致」约定的__hash__方法。

正确的实现方案

你想要的效果是:只要新交易的a在历史交易中出现过,或者b在历史交易中出现过,就拒绝插入。这种场景不要靠修改类的__eq__和__hash__实现,单独维护两个去重集合即可:

seen_a = set()
seen_b = set()
transactions = [] # 或者用set存,按需选择

def add_transaction(t: Transaction) -> bool:
    if t.a in seen_a or t.b in seen_b:
        return False # 重复,插入失败
    seen_a.add(t.a)
    seen_b.add(t.b)
    transactions.append(t)
    return True

这个方案逻辑清晰,性能也能保证O(1)的插入判断效率,完全满足你的需求。

不推荐的硬实现方式

如果非要强行写__hash__满足约定,你只能让所有Transaction对象返回同一个固定哈希值:

def __hash__(self):
    return 0

但这么做的后果是set插入的时间复杂度会直接退化成O(n),每次插入都要和已有的所有元素调用__eq__比较,而且因为相等逻辑不满足传递性,还是会出现不符合预期的去重结果,完全不推荐在生产环境使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 16:36:03