TreeNode类==运算符重写始终返回false问题排查求助
==运算符始终返回False的原因 这种情况大概率是__eq__方法的实现踩了Python的常见坑,我帮你梳理几个最可能的问题和解决办法:
最常见的错误:方法名写错了
很多人会不小心把__eq__写成__eq(少了末尾的下划线),或者_eq_(两边各一个下划线)。Python中特殊方法必须严格遵循__方法名__的格式,少一个下划线的话,Python会直接忽略你的自定义实现,转而使用默认的__eq__——默认逻辑是比较对象的内存身份(相当于is运算符),哪怕两个TreeNode的内容完全一样,只要是不同实例,就会返回False。
检查你的代码,__eq__的写法必须是:
def __eq__(self, other): # 你的比较逻辑
第二个坑:没有处理类型判断
如果你的__eq__里直接去访问other.val、other.left,但没有先判断other是不是TreeNode的实例,那么当比较对象是None或者其他类型时,要么直接抛出AttributeError,要么在异常被吞掉的场景下返回False。
正确的做法是先判断类型:
def __eq__(self, other): # 先判断other是否是TreeNode(或其子类)的实例 if not isinstance(other, TreeNode): return False # 递归比较所有关键属性 return (self.val == other.val and self.left == other.left and self.right == other.right)
第三个坑:比较逻辑不完整或错误
比如你只比较了self.val == other.val,但没比较左右子节点,那两个val相同但子节点不同的TreeNode会被误判;或者你用了is而不是==来比较属性(比如self.left is other.left),这会比较子节点的内存身份而非内容,哪怕两个子节点内容一致,只要是不同实例就会返回False。
记住,TreeNode是递归结构,要递归比较所有相关属性,并且用==来比较内容,而非is。
额外提醒:重写__eq__后记得重写__hash__
虽然这不会影响==的判断结果,但如果之后你想把TreeNode实例放到集合(比如set)或者作为字典的键,就会出问题——Python要求相等的对象必须有相同的哈希值。默认哈希是基于对象身份的,所以你需要自定义__hash__:
def __hash__(self): # 基于val、left、right的哈希值组合,None的哈希无需额外处理 return hash((self.val, self.left, self.right))
快速排查步骤
- 先确认
__eq__的方法名完全正确(前后各两个下划线); - 测试最简单的场景:创建两个val相同、左右子节点都是
None的TreeNode,用==比较,看是否返回True; - 如果还是不行,打印
other的类型,确认比较的对象都是TreeNode实例; - 逐步调试
__eq__里的每一个比较条件,定位哪一步返回了False。
内容的提问来源于stack exchange,提问作者charlieroth

