在python中按属性删除对象列表中的重复项
我有一个函数,我想一次浏览一个自定义对象列表(具有给定的中点),并获取具有唯一中点的对象,然后将它们放入新列表中。下面的代码给了我一个错误,列表没有名为“中点”的属性,但我不确定如何获取代码来搜索列表中具有匹配中点的对象。有人有建议吗在python中按属性删除对象列表中的重复项,python,list,object,attributes,Python,List,Object,Attributes,我有一个函数,我想一次浏览一个自定义对象列表(具有给定的中点),并获取具有唯一中点的对象,然后将它们放入新列表中。下面的代码给了我一个错误,列表没有名为“中点”的属性,但我不确定如何获取代码来搜索列表中具有匹配中点的对象。有人有建议吗 class Obj(): def __init__(self, midPoint=[0,0]): self.midPoint = midPoint obj1 = Obj(midPoint = [1,1]) obj2 = Obj(midPo
class Obj():
def __init__(self, midPoint=[0,0]):
self.midPoint = midPoint
obj1 = Obj(midPoint = [1,1])
obj2 = Obj(midPoint = [2,2])
obj3 = Obj(midPoint = [3,3])
obj4 = Obj(midPoint = [1,1])
obj5 = Obj(midPoint = [2,2])
l = [obj1, obj2, obj3, obj4, obj5]
list_no_duplicates = []
def Delete_duplicates(list1):
for i in list1:
if i.midPoint not in list_no_duplicates.midPoint:
list_no_duplicates.append(x)
Delete_duplicates(l)
print list_no_duplicates
您可以使用with函数从列表中删除重复条目。例如:
>>> from itertools import groupby
>>> [next(obj) for i, obj in groupby(sorted(l, key=lambda x: x.midPoint), lambda x: x.midPoint)]
[Obj: midPoint [1, 1], Obj: midPoint [2, 2], Obj: midPoint [3, 3]]
在这里,我将函数添加到您的Obj
类中,以显示带有类对象的中点的值:
def __repr__(self):
return 'Obj: midPoint {}'.format(str(self.midPoint))
注意:此解决方案不会保持原始列表中元素的顺序。新列表将根据中点的值进行排序
以下是完整的代码供您参考:
from itertools import groupby
class Obj():
def __init__(self, midPoint=[0,0]):
self.midPoint = midPoint
def __repr__(self):
return 'Obj: midPoint {}'.format(str(self.midPoint))
obj1 = Obj(midPoint = [1,1])
obj2 = Obj(midPoint = [2,2])
obj3 = Obj(midPoint = [3,3])
obj4 = Obj(midPoint = [1,1])
obj5 = Obj(midPoint = [2,2])
l = [obj1, obj2, obj3, obj4, obj5]
# `print(l)` will display:
# [Obj: midPoint [1, 1], Obj: midPoint [2, 2], Obj: midPoint [3, 3], Obj: midPoint [1, 1], Obj: midPoint [2, 2]]
# New list with unique `midPoint`s
new_list = [next(obj) for i, obj in groupby(sorted(l, key=lambda x: x.midPoint), lambda x: x.midPoint)]
# `print(new_list)` will display:
# [Obj: midPoint [1, 1], Obj: midPoint [2, 2], Obj: midPoint [3, 3]]
使用itertools.groupby
from itertools import groupby
from operator import attrgetter as ga
...
l2 = [next(g) for k, g in groupby(sorted(l, key=ga('midPoint')), key=ga('midPoint'))]
我们可以使用带有setdefault的dict,使用键作为中点的元组,使用值作为列表,然后将其附加到
然后我们有一个dict,其中每个中点的值都有一个列表,我们可以迭代第[0]个元素:
def Delete_duplicates(list1):
deduped = {}
for i in list1:
deduped.setdefault(tuple(i.midPoint),[]).append(i)
return [j[0] for i,j in deduped.items()]
如果您希望删除所有重复的列表,我们也可以这样做,但仅当列表长度为1时返回:
def Delete_duplicates(list1):
deduped = {}
for i in list1:
deduped.setdefault(tuple(i.midPoint),[]).append(1)
return [i for i in list1 if len(deduped[tuple(i.midPoint)]) == 1]
如果您不关心新列表中对象的顺序,可以使用dict
来实现这一点:
new_list = {tuple(obj.midPoint): obj for obj in l}.values()
# content of `new_list` will be:
# [Obj: midPoint [3, 3], Obj: midPoint [1, 1], Obj: midPoint [2, 2]]
创建一个字典,其中key作为中点
值的元组,value作为Obj
类的对象。然后调用dict.values()
方法获取值列表,即案例中的Obj
对象列表
但是,在Python3.x中,dict.values()返回一个dict.values类型的对象。要将其转换为列表,请显式键入cast tolist
,如下所示:
new_list = list(new_list)
如果我理解正确,这可能会按照你的要求工作
class Obj():
def __init__(self, midPoint=[0,0]):
self.midPoint = midPoint
obj1 = Obj(midPoint = [1,1])
obj2 = Obj(midPoint = [2,2])
obj3 = Obj(midPoint = [3,3])
obj4 = Obj(midPoint = [1,1])
obj5 = Obj(midPoint = [2,2])
l = [obj1, obj2, obj3, obj4, obj5]
list_no_duplicates = []
# determines if midpoint already exists in any object inside list_no_duplicates
def midpoint_exists(midpoint):
for obj in list_no_duplicates:
if obj.midPoint == midpoint:
return True
return False
def Delete_duplicates(list1):
for obj in list1:
# if there are no object with this midPoint, appends
if not midpoint_exists(obj.midPoint):
list_no_duplicates.append(obj)
Delete_duplicates(l)
print list_no_duplicates
列表的可能重复项\u无重复项
是一个列表,没有中点
属性。如果希望查看此属性,则需要手头有一个对象
对象。另外,在列表无重复项。追加(x)
行中,什么是x
?是否要在新列表中保持对象的顺序?是否要删除>=2个条目的对象,还是只保留其中一个?抱歉,我的意思是在“列表无重复项。追加(x)”中我不是x。订单不需要维护,我只想保留1份副本。谢谢