使用Python删除对象列表中的重复项

imn*_*mns 18 python mysql sqlobject

我有一个对象列表,我有一个充满记录的数据库表.我的对象列表有一个title属性,我想从列表中删除任何具有重复标题的对象(保留原始标题).

然后我想检查我的对象列表是否有数据库中任何记录的重复,如果是,请在将它们添加到数据库之前从列表中删除这些项目.

我已经看到了从这样的列表中删除重复项的解决方案:myList = list(set(myList)),但我不确定如何使用对象列表执行此操作?

我也需要维护对象列表的顺序.我也想也许我可以difflib用来检查标题的差异.

von*_*hev 39

set(list_of_objects),如果你知道一个重复的是什么,只会删除重复的,也就是说,你需要定义一个对象的唯一性.

为了做到这一点,你需要使对象可以清洗.你需要定义两者__hash____eq__方法,这里是如何:

http://docs.python.org/glossary.html#term-hashable

但是,您可能只需要定义__eq__方法.

编辑:如何实现该__eq__方法:

正如我所提到的,你需要知道对象的唯一性定义.假设我们有一本带有属性author_name和title的书,他们的组合是独一无二的(因此,我们可以有许多书籍由Stephen King撰写,许多书名为The Shining,但只有一本书名为The Shining by Stephen King),然后执行如下:

def __eq__(self, other):
    return self.author_name==other.author_name\
           and self.title==other.title
Run Code Online (Sandbox Code Playgroud)

同样,这是我有时实现该__hash__方法的方式:

def __hash__(self):
    return hash(('title', self.title,
                 'author_name', self.author_name))
Run Code Online (Sandbox Code Playgroud)

您可以检查如果您创建具有相同作者和标题的2本书的列表,则书籍对象将是相同的(使用is运算符)并且相同(使用==运算符).此外,set()使用时,它将删除一本书.

编辑:这是我的一个旧版本,但我现在才注意到它的错误在最后一段中用删除线修正:与之相比,具有相同的对象hash()不会给出.但是,如果您打算将它们用作set的元素或作为字典中的键,则使用对象的可用性.Trueis

  • 很好,我不知道`__hash__`和`__eq__`。有关如何实现“__eq__”的任何示例? (3认同)
  • 您需要确保类是相同的,否则该字段将不可用,因此 eq 还需要执行 `self.__class__ == other.__class__ 和 self.author_name==other.author_name\ 和 self.title==other.title ` (2认同)

aar*_*ing 10

由于它们不可清洗,因此您无法直接使用套装.标题应该是.

这是第一部分.

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)
Run Code Online (Sandbox Code Playgroud)

您将需要描述您在第二部分使用的数据库/ ORM等.


hug*_*own 6

这看起来相当小:

new_dict = dict()
for obj in myList:
    if obj.title not in new_dict:
        new_dict[obj.title] = obj
Run Code Online (Sandbox Code Playgroud)


Dav*_*ave 6

如果您不能(或不会)定义__eq__对象,您可以使用字典理解来达到相同的目的:

unique = list({item.attribute:item for item in mylist}.values())
Run Code Online (Sandbox Code Playgroud)

请注意,这将包含给定键的最后一个实例,例如mylist = [Item(attribute=1, tag='first'), Item(attribute=1, tag='second'), Item(attribute=2, tag='third')]您 get [Item(attribute=1, tag='second'), Item(attribute=2, tag='third')]mylist[::-1]您可以通过使用(如果存在完整列表)来解决此问题。