Python:如何通过对象属性过滤列表中的重复项?
class a:
b = 1
thing = a()
thing2 = a()
thing3 = a()
thing3.b = 2
lst = [thing,thing2,thing3]
我想是这样的:
lst = filter_out(obj.b==obj2.b,lst)
结果(与相同属性的对象进行筛选,以便只有一个左起):
[thing2,thing3]
这是如何实现的?据我所知,lambda过滤器不能用于比较列表中的两个对象。
使用字典来映射对象的b
属性。由于字典不能包含两次b
,字典的值将成为您独特的元素。
>>> unique = {}
>>> for x in lst:
... unique[x.b] = x
...
>>> list(unique.values())
[<__main__.a object at 0xb724cfcc>, <__main__.a object at 0xb724cfec>]
根据您是否要保留第一个或最后一个独特的项目,无论是覆盖现有值(如上面的代码)或添加项目之前添加if x.b not in unique
检查。
或者,如果你不想覆盖,请执行'unique.setdefault(xb,x)' – Artyer
可以使用,也groupby
从itertools
模块,像这样的例子:
from itertools import groupby
class A:
b = 1
thing = A()
thing2 = A()
thing3 = A()
thing3.b = 2
lst = [thing, thing2, thing3]
# For testing purpose
dct_id = {id(thing): "thing", id(thing2): "thing2", id(thing3): "thing3"}
# groupping based on each object's b value
sub = [list(v)[-1] for _, v in groupby(lst, lambda x: x.b)]
# check the groupped objects by their id
for k in sub:
print(dct_id[id(k)])
输出:
thing2
thing3
编辑:感谢@ tobias_k的评论
如果我们有这种物体:
thing = A()
thing2 = A()
thing3 = A()
thing2.b = 2
lst = [thing, thing2, thing3]
为了避免不好的结果,我们需要通过其对象的b值sort lst
。所以sub
将变为:
sub = [list(v)[-1] for _, v in groupby(sorted(lst, key=lambda x: x.b), lambda x: x.b)]
并重复同样的测试,我们将有:
thing3
thing2
PS:,最好在任何情况下进行排序sub
列表,以避免不好的结果。
'thing2.b = 2'而不是'thing3.b = 2'。这只适用于具有相同'key'值的元素彼此相邻的情况。 –
@tobias_k好点!所以在这种情况下,我需要根据对象的b值对'lst'进行排序。查看我最近的更新。 –
不应该是'[thing,thing2]'吗? –
'Class'语法无效。它应该是'class'。 –
@WillemVanOnsem我想删除重复的,过滤器部分有点混乱,所以我改变了 – Pear