How to remove `duplicates' in list of instances
我有一个特定类的实例列表。此列表包含"重复项",即重复项共享完全相同的属性。我要删除此列表中的重复项。
我可以使用
1 2 3 4 | class MyClass: def __eq__(self, other) : return self.__dict__ == other.__dict__ |
当然,我可以迭代整个实例列表,并逐元素比较它们以删除重复的实例,但是我想知道是否有一种更纯粹的方法可以做到这一点,最好使用in operator+list理解。
集合不能包含重复元素。
你可以做
1 2 3 4 5 6 | def uniquify(content): result = [] for element in content: if element not in result: result.append(element) return result |
这将继续向输出列表追加元素,除非它们已经在输出列表中。
在定位球法上再多一点。您可以通过委托给元组的散列来安全地实现散列-只需散列一个包含您要查看的所有属性的元组。您还需要定义一个行为正常的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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) |
当你做了这么多tuple构造时,你可以让你的类变得不可更改:
1 2 | def __iter__(self): return iter((self.a, self.b, self.c)) |
这使您可以在
然后您可以这样做:
1 2 | def unordered_elim(l): return list(set(l)) |
如果您想保留订单,可以使用
1 2 3 4 | from collections import OrderedDict def ordered_elim(l): return list(OrderedDict.fromkeys(l).keys()) |
这应该比使用
1 2 3 4 5 6 7 | 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)) |
使用此输出:
1 2 | [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')] |
注意,如果您的任何属性不可散列,这将不起作用,您要么需要绕过它(将列表更改为元组),要么使用像