Python如何保证集合元素唯一?集合判断对象相等的规则是什么?
Python集合判断元素重复的逻辑
Python集合判断两个元素是否为同一元素的判断流程分为两步,二者必须同时满足才会被判定为重复元素,新加入的元素会被去重:
- 第一步:计算两个元素的哈希值,若哈希值不同,直接判定为不同元素,不会进入下一步校验
- 第二步:如果哈希值相同,再调用
__eq__方法判断两个对象是否相等,仅当__eq__返回True时,才会判定为同一元素
问题产生的原因
你的示例代码中仅重写了__hash__方法,没有重写__eq__方法。自定义类默认的__eq__方法是对比两个对象的内存地址,你创建的两个Obj实例是不同的对象,内存地址不同,因此默认__eq__返回False,集合会判定二者是不同元素,所以都被存入集合。
符合预期的写法
如果需要按照message属性判断两个对象是否为同一集合元素,需要同时重写__hash__和__eq__方法,示例如下:
class Obj: def __init__(self, message, value): self.message = message self.value = value def __hash__(self): return hash(self.message) def __eq__(self, other): # 只有同类型且message属性相等时,才判定为相同对象 if isinstance(other, Obj): return self.message == other.message return False s = set([Obj("1", 1), Obj("1", 2)]) # 此时集合中仅会保留第一个添加的Obj("1", 1)实例
注意事项
Python官方约定:如果两个对象a == b返回True,那么hash(a)和hash(b)的返回值必须相等。如果自定义类需要作为集合元素或者字典的键,必须遵守这个约定,同时重写__eq__和__hash__方法,否则会出现不符合预期的行为。
内容的提问来源于stack exchange,提问作者midugh
相关产品推荐
相关产品推荐

