【发布时间】:2023-03-06 12:46:01
【问题描述】:
我想比较对象并在它们接近时声明它们相等。
这里我有一个类Person,它具有name、age 和sex 属性。如果两个人的名字相同,并且年龄在彼此的容忍范围内,与性别无关,我希望他们被确定为同一个人。
我曾希望按以下方式执行此操作,但这不起作用,因为声明相等的对象必须具有相同的哈希值。
在下面的示例中,我希望 set(People) 仅返回一个人,因为我没有比较 sex,而且他们都有相同的名字,并且他们的年龄在 tol 范围内。
有没有干净的方法来解决这个问题?
#!/usr/bin/python
tol=5
class Person:
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
def __repr__(self):
return repr((self.name, self.age, self.sex))
def __eq__(self, other):
return self.name==other.name and (abs(self.age-other.age)<tol)
def __hash__(self):
return hash((self.name,self.age))
names=["James Jones", "James Jones", "James Jones"]
ages = [47.53,47.53,47.531]
sexes=["M","F","M"]
People=[]
for i in range(3):
People.append(Person(names[i],ages[i],sexes[i]))
for person in set(People):
print person
【问题讨论】:
-
您不应该根据数值接近性来定义相等,因为它不具有传递性。如果您对 11、14 和 17 岁的人进行了类似命名,那么前两个将是“相等”,后两个是“相等”,但第一个和最后一个不是“相等”。那么您希望保留哪些?
-
你可以从你的
__hash__函数中删除self.age,但你仍然会遇到@khelwood所说的同样的问题 -
好的。因此,计算所有同名的人的平均年龄,并将所有在均值范围内的人计算为同一个人。我想在这个框架内没有一种干净的方法可以做到这一点?
-
但这不起作用,因为我正在寻找集群。我想我可以定义一个集群大小,然后找到彼此在集群大小内的所有同名的人,计算平均年龄并定义集群的平均人并保留那个人。我想我应该根据这些标准简单地构建一个新列表?
-
当然,集群也不需要是可传递的,但这并不重要。数据是聚类的。我正在尝试计算具有相同名称的集群的数量。如果我有五个人在一个集群中,三个人在另一个集群中,我希望最终有两个人,这可能是两个集群中每个集群的平均人,或者它可能只是两个集群中每个集群的代表人。
标签: python comparison-operators