如何删除`重复'在实例列表中

时间:2017-10-04 14:18:13

标签: python class duplicates instance

我有一个特定类的实例列表。此列表包含`duplicates',在重复项共享完全相同的属性的意义上。我想从此列表中删除重复项。

我可以使用

检查两个实例是否共享相同的属性
class MyClass:

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

我当然可以迭代整个实例列表并逐个元素地比较它们以删除重复项,但我想知道是否有更多的pythonic方法来执行此操作,最好使用in运算符+列表理解。

2 个答案:

答案 0 :(得分:4)

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

这将继续将元素附加到输出列表,除非它们已经在输出列表中。

答案 1 :(得分:2)

关于设定方法的更多信息。您可以通过委托给元组的哈希来安全地实现哈希 - 只需哈希一个您想要查看的所有属性的元组。您还需要定义一个行为正常的__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))

这使您可以在tuple上致电self而不是费力地执行.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')]

请注意,如果您的任何属性无法播放,则无法正常工作,并且您需要解决此问题(将列表更改为元组)或使用缓慢的{{ {1}}类似于n ^ 2