使用Python删除对象列表中的重复项
我有一个对象列表,还有一个数据库表,里面有很多记录。我的对象列表有一个标题属性,我想从列表中删除任何标题重复的对象(保留原始标题) 然后,我想检查我的对象列表是否与数据库中的任何记录有任何重复项,如果有,请在将这些项添加到数据库之前从列表中删除这些项 我见过这样的从列表中删除重复项的解决方案:使用Python删除对象列表中的重复项,python,mysql,sqlobject,Python,Mysql,Sqlobject,我有一个对象列表,还有一个数据库表,里面有很多记录。我的对象列表有一个标题属性,我想从列表中删除任何标题重复的对象(保留原始标题) 然后,我想检查我的对象列表是否与数据库中的任何记录有任何重复项,如果有,请在将这些项添加到数据库之前从列表中删除这些项 我见过这样的从列表中删除重复项的解决方案:myList=list(set(myList)),但我不知道如何使用对象列表来实现这一点 我还需要维护我的对象列表的顺序。我也在想也许我可以使用difflib检查标题中的差异。因为它们不可散列,所以不能直接
myList=list(set(myList))
,但我不知道如何使用对象列表来实现这一点
我还需要维护我的对象列表的顺序。我也在想也许我可以使用difflib检查标题中的差异。因为它们不可散列,所以不能直接使用集合。标题应该是这样的 这是第一部分
seen_titles = set()
new_list = []
for obj in myList:
if obj.title not in seen_titles:
new_list.append(obj)
seen_titles.add(obj.title)
您需要描述第二部分使用的是什么数据库/ORM等。这似乎非常简单:
new_dict = dict()
for obj in myList:
if obj.title not in new_dict:
new_dict[obj.title] = obj
集合(对象列表)
仅在您知道什么是重复项时才会删除重复项,也就是说,您需要定义对象的唯一性
为了做到这一点,您需要使对象可散列。您需要同时定义\uuuuuuuuuuuuuuuuuuuuuuuuuuuuu散列
和\uuuuuuuuuuuuuueq
方法,以下是如何定义的:
不过,您可能只需要定义方法
编辑:如何实现均衡方法:
def __hash__(self):
return hash(('title', self.title,
'author_name', self.author_name))
正如我提到的,您需要知道对象的唯一性定义。假设我们有一本书,其属性author_name和title的组合是唯一的(因此,我们可以有许多书是斯蒂芬·金(Stephen King)编写的,许多书被命名为Shining,但只有一本书被斯蒂芬·金(Stephen King)命名为Shining),那么实现如下:
def __eq__(self, other):
return self.author_name==other.author_name\
and self.title==other.title
类似地,我有时也是这样实现\uuuuuuuuuuu散列法的:
def __hash__(self):
return hash(('title', self.title,
'author_name', self.author_name))
您可以检查,如果创建一个包含两本具有相同作者和标题的书籍的列表,则书籍对象将相同(使用is
运算符)且相等(使用=
运算符)。另外,当使用set()
时,它将删除一本书
EDIT:这是我的一个老问题,但我现在才注意到它有一个错误,在最后一段中用删除线更正了这个错误:与is
相比,具有相同hash()
的对象不会给出True
。但是,如果要将对象用作集合元素或字典中的键,则可以使用对象的哈希性。这很容易:-
a=[5,6,7,32,32,32,32,32,32,32,32]
a=列表(集合(a))
印刷品(a)
就这样!:) 如果要保留原始顺序,请使用它:
seen = {}
new_list = [seen.setdefault(x, x) for x in my_list if x not in seen]
如果您不介意订购,请使用:
new_list = list(set(my_list))
为此,需要\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
和\uuuuuuuuuuuuuu
将对象添加到集合中需要\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。默认情况下,数字、字符串和元组等不可变对象是可散列的
然而,由于鸽子洞原理,哈希冲突(两个不同的对象哈希到相同的值)是不可避免的。因此,不能仅使用散列来区分两个对象,用户必须指定自己的\uuuuueq\uuuu
函数。因此,用户提供的实际哈希函数并不重要,但最好避免哈希冲突以提高性能(请参阅)。我最近使用了下面的代码。它与其他答案类似,它在列表上迭代并记录它看到的内容,然后删除它已经看到的任何项目,但它不会创建重复的列表,而是从原始列表中删除该项目
seen = {}
for obj in objList:
if obj["key-property"] in seen.keys():
objList.remove(obj)
else:
seen[obj["key-property"]] = 1
离开原作,这意味着什么?因为如果像你说的那样,你想保持列表的顺序,那么列表中第一个出现的重复对象将是原始对象,对吗?是的,我只是想删除除原始对象之外的所有重复对象@洛特,我找了很多东西,但什么也没找到,这就是我来这里的原因。你能举一个例子来说明这个问题吗?我很乐意看到。.我正在使用mysql和sqlobject。@bababa请更新这个问题,以便其他人也能看到它。@bababa,我看不到使用sqlobject做这件事的好方法(即不在一次查询中从数据库中提取每个对象或对每个对象进行一次查询)所以我会等一会儿,然后如果比我更不了解sqlobject的人没有出现,我会发布这篇文章。很好,我不知道\uuuuuuuhash\uuuuuu
和\ueq\uuuuu
。关于如何实现\uuuu eq\uuuu
的任何示例?您需要确保类相同或字段不可用,以便eq还需要执行self.\uuu class\uuuuuu==other.\uu class\uuuuuuu=和self.author\u name\和self.title==other.title
在包含对象的列表上无法执行此操作。只有在objList包含可比较的对象(即实现eq方法)。有关详细信息,请参见创建重复数据消除列表将适用于未实现eq的对象。