2016-04-01 15 views
0

nehme an, ich habe eine Klassendefinition wie dieseEinzigartige Klasseninstanzen in Python3

class structure: 
    def __init__(self, handle): 
     self.handle = handle 

Wie kann ich numpy.unique oder ein anderes Werkzeug von Python3 einzigartige Elemente in einer Liste von Instanzen dieser Klasse zu finden? Der Vergleich sollte in Bezug auf den Wert des Feldes 'handle' durchgeführt werden.

+0

Möchten Sie die Werte für Handle oder die Instanzen? Wenn Sie möchten, dass die Instanzen und zwei Instanzen denselben Wert für handle haben, was sollte gewählt werden? – snakecharmerb

Antwort

6

numpy.unique ist nicht das beste Werkzeug für benutzerdefinierte Klassen. Machen Sie Ihre Instanzen hashable (implementierende __hash__ und __eq__), dann einen Satz verwenden, um eine Liste der Instanzen auf eindeutige Werte zu reduzieren:

class structure: 
    def __init__(self, handle): 
     self.handle = handle 

    def __hash__(self): 
     return hash(self.handle) 

    def __eq__(self, other): 
     if not isinstance(other, structure): 
      # only equality tests to other `structure` instances are supported 
      return NotImplemented 
     return self.handle == other.handle 

Sets effizient Duplikate über den Hash erkennen kann, was bestätigt, dass die Objekte mit dem gleichen Hash sind auch gleich zuerst.

Um die eindeutigen Instanzen zu erhalten, einfach set() auf einer Folge von Instanzen nennen:

unique_structures = set(list_of_structures) 

Demo:

>>> class structure: 
...  def __init__(self, handle): 
...   self.handle = handle 
...  def __hash__(self): 
...   return hash(self.handle) 
...  def __eq__(self, other): 
...   if not isinstance(other, structure): 
...    # only equality tests to other `structure` instances are supported 
...    return NotImplemented 
...   return self.handle == other.handle 
...  def __repr__(self): 
...   return '<structure({!r})>'.format(self.handle) 
... 
>>> list_of_structures = [structure('foo'), structure('bar'), structure('foo'), structure('spam'), structure('spam')] 
>>> set(list_of_structures) 
{<structure('bar')>, <structure('foo')>, <structure('spam')>} 

in Betracht zu nehmen, dass der Hash jeder structure Instanz in einem Satz gespeichert oder verwendet einen Wörterbuchschlüssel darf nicht geändert werden; Das handle Attribut während der Lebensdauer einer Instanz nicht zu ändern ist der einfachste Weg, dies sicherzustellen.

+0

Könnte ich Sie bitten, den Grund für die Eingabe von "Wenn nicht in der Instanz" zu erläutern? – Macaronnos

+0

@Macaronnos: Vergleichsmethoden wie '__eq__' sollten' NotImplemented' immer für Vergleiche zurückgeben, die sie nicht unterstützen; Es hat wenig Sinn, Gleichheitsprüfungen mit etwas anderem als "Struktur" -Instanzen zu unterstützen. –

+0

Oh, genau. Vielen Dank. – Macaronnos