2010-11-12 200 views
12

我有一個對象列表,並且我有一個充滿記錄的db表。我的對象列表具有標題屬性,我想從列表中刪除具有重複標題的任何對象(保留原始對象)。用Python刪除對象列表中的重複項

然後我想檢查我的對象列表是否有數據庫中任何記錄的任何重複項,如果是,請在將它們添加到數據庫之前從列表中刪除這些項。

我已經看到了從這樣的列表中刪除重複項的解決方案:myList = list(set(myList)),但我不知道如何使用對象列表來做到這一點?

我也需要維護對象列表的順序。我也在想,也許我可以用difflib來檢查標題中的差異。

+4

步驟1.搜索。在Python編程類中每學期都會使用這種確切的措詞。請搜索。 – 2010-11-12 21:38:45

+0

__leaving original__,這是什麼意思?因爲如果像你說過的那樣,你希望__維護列表中的order__,那麼列表中第一次出現重複對象將是原始權利? – mouad 2010-11-12 21:56:24

+0

是的,我的意思是我想刪除除原來的所有副本。 @ S.Lott,我搜索了很多東西,但沒有找到任何東西,這就是我來到這裏的原因。你能舉出一個解決這個確切問題的例子嗎?我很樂意看到它。 – imns 2010-11-12 22:25:22

回答

28

set(list_of_objects)如果你知道一個重複的是什麼,只會刪除重複的,也就是說,你需要定義一個對象的唯一性。

爲了做到這一點,您需要使對象可哈希。您需要定義兩個__hash____eq__方法,這裏是如何:

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

雖然,你可能只需要定義__eq__方法。

編輯:如何實現__eq__方法:

你需要知道,正如我所說,你的對象的唯一性定義。假設我們有一本帶有屬性author_name和title的書,它們的組合是獨一無二的(所以我們可以有很多Stephen King編寫的書,還有很多書叫做The Shining,但只有一本書叫Stephen King的Shining),那麼實現如下:

def __eq__(self, other): 
    return self.author_name==other.author_name\ 
      and self.title==other.title 

同樣的,這是我有時實施__hash__方法:

def __hash__(self): 
    return hash(('title', self.title, 
       'author_name', self.author_name)) 

您可以檢查,如果你創建的兩本書用相同的作者和書名,書列表對象將是相同的(與is運營商)和等於(與==運營商)。此外,當使用set()時,它將刪除一本書。

編輯:這是我的一個老anwser,但我現在才發現,它具有與刪除線最後一段更正錯誤:與同hash()對象時is相比不會給True 。但是,如果您打算將它們用作集合的元素,或者將其用作字典中的鍵,則可以使用對象的可哈希性。

+0

不錯,我不知道'__hash__'和'__eq__'。任何關於如何實現'__eq__'的例子? – imns 2010-11-14 17:02:19

+0

請參閱上面的編輯 – vonPetrushev 2010-11-15 13:09:49

6

由於它們不可散列,因此不能直接使用集合。標題應該是。

這是第一部分。

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等你用於第二部分雖然。

+0

我在sqlobject中使用mysql。 – imns 2010-11-12 22:07:50

+0

@bababa請更新問題,以便其他人也能看到它。 – aaronasterling 2010-11-12 22:14:52

+0

@bababa,我沒有看到使用sqlobject做這件事的好方法(也就是說,在一個查詢中沒有從數據庫中拉出每個對象,或者每個對象都有一個查詢),所以我會等一會兒,然後發佈,如果有人不知道比我更好的sqlobject不來。 – aaronasterling 2010-11-12 23:49:30

1

這似乎相當小:

new_dict = dict() 
for obj in myList: 
    if obj.title not in new_dict: 
     new_dict[obj.title] = obj 
0

其相當容易freinds: -

一個= [5,6,7,32,32,32,32,32,32,32,32]

一個=列表(集的(a))

打印的(a)

[5,6,7,32] 

多數民衆贊成它! :)

+5

無法在包含對象的列表上執行此操作。 – 2014-09-21 00:00:45

0

如果你想保留原來的順序使用:

seen = {} 
new_list = [seen.setdefault(x, x) for x in my_list if x not in seen] 

如果你不在乎訂購然後用它的:

new_list = list(set(my_list))