2010-11-12 11 views
12

Ich habe eine Liste von Objekten und ich habe eine db-Tabelle voller Datensätze. Meine Liste von Objekten hat ein Titelattribut und ich möchte alle Objekte mit doppelten Titeln aus der Liste entfernen (das Original belassen).Entfernen Sie Dubletten in der Objektliste mit Python

Dann möchte ich überprüfen, ob meine Liste von Objekten irgendwelche Duplikate von irgendwelchen Datensätzen in der Datenbank hat, und wenn dies der Fall ist, entfernen Sie diese Elemente aus der Liste, bevor Sie sie der Datenbank hinzufügen.

Ich habe Lösungen zum Entfernen von Duplikaten aus einer Liste wie folgt gesehen: myList = list(set(myList)), aber ich bin mir nicht sicher, wie man das mit einer Liste von Objekten macht?

Ich muss die Reihenfolge meiner Liste von Objekten auch beibehalten. Ich dachte auch, dass ich vielleicht difflib verwenden könnte, um nach Unterschieden in den Titeln zu suchen.

+4

Schritt 1. Suchen. Dieser genaue Wortlaut wird jedes Semester in der Programmierklasse Python verwendet. Bitte suchen. –

+0

__leaving the original__, was bedeutet das? Denn wenn Sie, wie Sie sagten, __maintained order__ der Liste haben wollen, so wird das erste Auftreten eines doppelten Objekts in der Liste das ursprüngliche Recht sein? – mouad

+0

Ja, ich wollte nur alle Duplikate außer dem Original entfernen. @ S.Lott, ich habe eine Tonne gesucht und habe nichts gefunden, deshalb bin ich hergekommen. Können Sie ein Beispiel nennen, das genau dieses Problem anspricht? Ich würde mich freuen, es zu sehen. – imns

Antwort

28

Die set(list_of_objects) nur die Duplikate entfernen, wenn Sie wissen, was ein Duplikat ist, das heißt, es eine Einzigartigkeit eines Objekts definieren müssen.

Um dies zu tun, müssen Sie das Objekt hashbar machen. Sie müssen sowohl __hash__ und __eq__ Methode definieren, ist hier, wie:

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

Obwohl, werden Sie wahrscheinlich nur __eq__ Methode definieren müssen.

EDIT: Wie die __eq__ Methode implementieren:

Sie wissen müssen, wie ich die Einzigartigkeit Definition des Objekts erwähnt. Angenommen, wir haben ein Buch mit den Attributen autor_name und titel, deren Kombination einzigartig ist (also können wir viele Bücher haben, die Stephen King verfasst hat, und viele Bücher namens Shining, aber nur ein Buch mit dem Namen The Shining von Stephen King), dann die Implementierung wird wie folgt:

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

und das ist, wie ich die __hash__ Methode manchmal implementieren:

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

können Sie überprüfen, dass, wenn Sie eine Liste von 2 Bücher mit demselben Autor und Titel erstellen, das Buch Objekte werden gleich sein (mit is Operator) und gleich (mit == Operator). Wenn set() verwendet wird, wird auch ein Buch entfernt.

EDIT: Dies ist eine alte anwser von mir, aber ich merke erst jetzt, dass er den Fehler aufweist, die mit durchgestrichener im letzten Absatz korrigiert wird: Objekte mit den gleichen hash() wird True nicht geben, wenn sie mit is verglichen . Die Hashalierbarkeit eines Objekts wird jedoch verwendet, wenn Sie beabsichtigen, sie als Elemente eines Satzes oder als Schlüssel im Wörterbuch zu verwenden.

+0

Schön, ich wusste nicht über '__hash__' und' __eq__'. Beispiele zur Implementierung von '__eq__'? – imns

+0

finden Sie die Bearbeitung oben – vonPetrushev

6

Da sie nicht hashbar sind, können Sie ein Set nicht direkt verwenden. Die Titel sollten aber sein.

Hier ist der erste Teil.

Sie müssen jedoch beschreiben, welche Datenbank/ORM usw. Sie für den zweiten Teil verwenden.

+0

Ich verwende mysql mit sqlobject. – imns

+0

@bababa bitte aktualisieren Sie die Frage, damit andere Leute es auch sehen. – aaronasterling

+0

@bababa, sehe ich keinen guten Weg, dies mit sqlobject zu tun (dh ohne jedes Objekt aus der DB in einer Abfrage oder eine Abfrage pro Objekt zu ziehen), so werde ich eine Weile warten und dann, wenn jemand das weiß nicht, sqlobject besser als ich nicht mitkommen. – aaronasterling

1

Das scheint ziemlich minimal:

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

Seine ganz einfach freinds: -

a = [5,6,7,32,32,32,32,32,32,32,32]

ein = list (set (a))

print (a)

[5,6,7,32] 

das ist es! :)

+5

Dies kann nicht auf einer Liste, die Objekte enthält. –

0

Wenn Sie die ursprüngliche Reihenfolge sie bewahren wollen verwenden:

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

Wenn Sie kümmern sich nicht dann von der Bestellung es verwenden:

new_list = list(set(my_list))