【问题标题】:removing near duplicate objects in Python list删除 Python 列表中近乎重复的对象
【发布时间】:2023-03-06 12:46:01
【问题描述】:

我想比较对象并在它们接近时声明它们相等。

这里我有一个类Person,它具有nameagesex 属性。如果两个人的名字相同,并且年龄在彼此的容忍范围内,与性别无关,我希望他们被确定为同一个人。

我曾希望按以下方式执行此操作,但这不起作用,因为声明相等的对象必须具有相同的哈希值。

在下面的示例中,我希望 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


【解决方案1】:

除了将进行比较的__eq__() 方法之外,您还必须实现一个__hash__() 方法,该方法将为应该被视为相同的对象返回相同的值。对于您的日期阈值,这可能很难。

【讨论】:

    猜你喜欢
    • 2019-04-07
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    • 2011-05-09
    • 2016-03-01
    • 2012-01-09
    • 2018-07-19
    相关资源
    最近更新 更多