Python:如何判断属性值匹配的对象是否存在于对象列表中?
解决Python中对象实例
in列表判断的问题 你遇到的这个问题其实是Python对象默认相等性判断的特性导致的——默认情况下,Python只会检查两个变量是否指向同一个内存地址的实例,根本不会去对比对象的属性值。就像你写的这段代码:
class Obj: def __init__(self, x, y): self.x = x self.y = y li = [Obj(0, 0), Obj(0, 1), Obj(2, 3)] print(Obj(2,3) in li) # 输出False
哪怕两个Obj的x和y完全一致,它们也是独立的实例,所以in操作符自然返回False。下面给你两种不用显式循环的简洁解决办法:
方法1:重写类的__eq__方法(推荐)
这是最一劳永逸的方式,直接告诉Python怎么判断两个Obj对象相等。只要重写__eq__方法,让它对比对象的x和y属性,in操作符就会自动用这个逻辑来判断:
class Obj: def __init__(self, x, y): self.x = x self.y = y def __eq__(self, other): # 先判断other是不是Obj的实例,避免和其他类型比较出错 if not isinstance(other, Obj): return False return self.x == other.x and self.y == other.y li = [Obj(0, 0), Obj(0, 1), Obj(2, 3)] print(Obj(2,3) in li) # 现在输出True
要是之后你需要把Obj对象放进集合(比如set)或者作为字典的键,还得重写__hash__方法(因为哈希集合依赖哈希值判断,默认哈希值是基于实例内存地址的),可以这么加:
class Obj: def __init__(self, x, y): self.x = x self.y = y def __eq__(self, other): if not isinstance(other, Obj): return False return self.x == other.x and self.y == other.y def __hash__(self): # 用x和y的哈希值组合成当前对象的哈希值 return hash((self.x, self.y))
方法2:用any()结合生成器表达式(无需修改原类)
如果你不想改动原有的Obj类,也可以用any()来替代显式循环,写法非常简洁——虽然底层还是循环,但代码里看不到循环的痕迹:
class Obj: def __init__(self, x, y): self.x = x self.y = y li = [Obj(0, 0), Obj(0, 1), Obj(2, 3)] target = Obj(2,3) print(any(obj.x == target.x and obj.y == target.y for obj in li)) # 输出True
不过这种方法每次判断都要写属性对比的逻辑,不如重写__eq__来得方便。
内容的提问来源于stack exchange,提问作者MrSir
相关产品推荐
相关产品推荐

