繁体   English   中英

如何在实例列表中删除“重复项”

[英]How to remove `duplicates' in list of instances

我有某个类的实例列表。 该列表包含“重复项”,即重复项具有完全相同的属性。 我想从此列表中删除重复项。

我可以通过使用以下命令检查两个实例是否共享相同的属性

class MyClass:

    def __eq__(self, other) : 
        return self.__dict__ == other.__dict__

我当然可以遍历整个实例列表,然后逐个元素地比较它们以删除重复项,但是我想知道是否还有更Python的方法来做到这一点,最好使用in运算符+列表理解。

set s(无顺序)

集合不能包含重复的元素。 list(set(content))将删除列表中的重复数据。 这并不是效率太低,并且可能是实现它的更好方法之一:P但是,您将需要为类定义__hash__函数,该函数对于相等的元素必须相同,对于不相等的元素必须不同,这样才能起作用。 请注意, hash值必须遵守上述规则,但是在运行之间可能会发生变化而不会引起问题。

index功能(稳定顺序)

您可以执行lambda l: [l[index] for index in range(len(l)) if index == l.index(l[index])] 这只会保留列表中的第一个元素。

in运算符中(稳定的顺序)

def uniquify(content):
    result = []
    for element in content:
        if element not in result:
            result.append(element)
    return result

除非将元素添加到输出列表中,否则它将继续将元素添加到输出列表中。

关于固定方法的更多信息。 您可以通过委派给元组的哈希来安全地实现哈希-只需对要查看的所有属性的元组进行哈希处理即可。 您还需要定义行为正确的__eq__

class MyClass:
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def __eq__(self, other):
        return (self.a, self.b, self.c) == (other.a, other.b, other.c)

    def __hash__(self):
        return hash((self.a, self.b, self.c))

    def __repr__(self):
        return "MyClass({!r}, {!r}, {!r})".format(self.a, self.b, self.c)

当您进行大量的元组构造时,您可以使您的类可迭代:

def __iter__(self):
    return iter((self.a, self.b, self.c))

这使您可以对self调用tuple ,而不必费力地执行.a, .b, .c等。

然后,您可以执行以下操作:

def unordered_elim(l):
    return list(set(l))

如果要保留顺序,可以改用OrderedDict

from collections import OrderedDict

def ordered_elim(l):
    return list(OrderedDict.fromkeys(l).keys())

这应该比使用inindex更快,同时仍保留顺序。 您可以像这样测试它:

data = [MyClass("this", "is a", "duplicate"),
        MyClass("first", "unique", "datum"),
        MyClass("this", "is a", "duplicate"),
        MyClass("second", "unique", "datum")]

print(unordered_elim(data))
print(ordered_elim(data))

输出如下:

[MyClass('first', 'unique', 'datum'), MyClass('second', 'unique', 'datum'), MyClass('this', 'is a', 'duplicate')]
[MyClass('this', 'is a', 'duplicate'), MyClass('first', 'unique', 'datum'), MyClass('second', 'unique', 'datum')]

注意:如果您的任何属性都不是可哈希的,那么它将无法正常工作,您要么需要解决它(将列表更改为元组),要么使用像in那样的慢速n ^ 2方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM