python - 在 Python 中,根据自定义比较过滤短列表以仅包含唯一值的巧妙方法是什么?

标签 python comparison unique overloading operator-keyword

我有一个简短的(1 - 5)自定义类实例列表,我想对其进行过滤,以便根据我的自定义比较,仅保留唯一的值。

什么是简单/简洁/Pythonic/快速的方法来做到这一点?我看到人们唯一化列表的正常方法是将它们通过 set() 进行处理,但这实际上并不适用,因为集合使用 __hash__ 进行比较,这不允许我与彼此单独对象。

额外:

我对唯一性的解释实际上就是让值之间的差异小于某个值。事实上,它更“接近”而不是“独特”。这就是为什么我不能只检查一个值是否已被使用,我需要检查一个值是否太接近任何其他值。

最佳答案

如果您将问题改写为每个对象生成每组比较相等的对象唯一的值,您仍然可以使用集合,但使用它来存储您认为是对象的值等于:

def unique_value(obj):
    return some_calculation_over(obj)

seen = set()
filtered = [obj for obj in yourlist if unique_value(obj) not in seen and not seen.add(unique_value(obj)]

另一种方法是无论如何实现__hash__,并确保它根据您的比较标准返回相同的值;例如被认为相等的对象具有相同的哈希值。您还需要实现一个 __eq__ 方法。

如果两个对象基于 2 个属性相等,则该值是这两个属性的元组。如果你可以计算一个数字,并且相同的数字意味着相同的物体,那么就这样做,等等。

当你想要删除对象簇时,方法没有太大不同;只需计算对象落入的桶即可。 “接近”的对象被分类到同一个存储桶中,为您留下唯一的值(存储桶标识符)。

要对一系列足够接近的对象进行聚类,也许您希望按属性对对象进行排序,然后挑选足够接近的元素:

def unique_close(lst, tolerance, key=None):
    if key is None:
        # identity
        key = lambda o: o
    items = iter(sorted(lst, key=key))
    first = next(items)
    prev = key(first)
    yield first
    for item in items:
        val = key(item)
        if abs(prev - val) > tolerance:
            yield item
        prev = val

此生成器根据您选择的键对元素进行排序(默认为元素本身),然后仅生成超出容差的元素。

演示:

>>> list(unique_close([1, 4, 5, 2, 3], 2))
[1]
>>> list(unique_close([1, 4, 5, 2, 22, 24, 3], 2))
[1, 22]
>>> list(unique_close([1, 4, 5, 2, 22, 24, 3], 3, key=lambda v: v * 2))
[1, 22, 24]

关于python - 在 Python 中,根据自定义比较过滤短列表以仅包含唯一值的巧妙方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23300911/

相关文章:

python - 如何使用python的多处理模块

python - 使用 scrapy 从 XKCD 中抓取图像

C++ 分数混合比较运算符错误

arrays - 比较两个数组并找出差异

MYSQL - 不同行的总和

python - 在 windows 7 中为 python 3.5 安装 pywin32

python - 同一页面上具有相同 radio 字段的多个 WTForm

sql - 比较postgres数据库中的两列

c++ - C/C++ 如何从 2 个数组中获取唯一值?

MYSQL - 如何获得第二个唯一字符串键?