题目
现在有一个用户类Person
,具有name
、sex
、age
三个属性,用这个类创造了多个用户,例如:
a = Person("张三", "男", 18)
b = Person("李四", "男", 20)
c = Person("李四", "男", 20)
把姓名name
和性别sex
相等的认为是同一个人,不考虑年龄age
,也就是说b和c是同一个人,需要去除一个,需要对这一批用户进行去重
答案
先说答案,首先定义一个Person
类, 然后实现其魔法方法__eq__
和__hash__
, 利用set对其实例去重,如下:
class Person:
def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age
def __repr__(self):
"""将对象以字符串的形式输出出来"""
return f"{self.name}-{self.sex}"
def __eq__(self, other):
return self.name == self.name and self.sex == self.sex
def __hash__(self):
return hash(self.name+self.sex)
a = Person("张三", "男", 18)
b = Person("李四", "男", 20)
c = Person("李四", "男", 20)
s = [a, b, c]
print(set(s))
# 输出如下
# {张三-男, 李四-男}
原理
set集合里的元素必须满足以下几个条件:
- 支持hash()函数,并且通过__hash__()方法所得到的哈希值是不变的
- 支持通过__eq__()方法来检测相等性
- 若a == b为 True,则 hash(a) == hash(b)也为True
如果实现了一个类的__eq__方法,并且希望它是可哈希的,那么就一定要实现一个相对应的__hash__方法,保证在a==b为真的情况下hash(a)==hash(b)也为真,否则就会破坏恒定的哈希算法,导致由这个类对象所组成的字段和集合完全失去可靠性