2017-01-23 1 views
1

Angenommen, ich habe einen eingehenden Nachrichtenstrom, den ich gerade verarbeite. Für jeden Artikel extrahiere ich einige Daten und speichere sie. Aber viele Dinge sind gleich. Ich möchte den Überblick behalten, aber nicht die gleichen Daten mehr als einmal speichern. Ich kann es so implementieren, aber es scheint klobig zu sein:Ist es normal ein Objekt als eigenen Schlüssel in einem Dictionary/hashmap (in Python) zu verwenden?

item_cache = {} 
item_record = [] 

def process(input_item): 
    item = Item(input_item) # implements __hash__ 
    try: 
     item_record.append(item_cache[item]) 
    except KeyError: 
     item_cache[item] = item # this is the part that seems weird 
     item_record.append(item) 

Ich bin nur darüber nachzudenken? Macht d[thing] = thing ein ziemlich normales Konstrukt in Python?

EDIT

Als Antwort unten zu kommentieren. Hier ist ein vollständigeres Beispiel, das zeigt, wie dieser Code vermeidet, doppelte Kopien von Eingabedaten zu speichern.

class Item(object): 
    def __init__(self, a, b, c): 
     self.a = a 
     self.b = b 
     self.c = c 

    def __eq__(self, other): 
     return self.a == other.a and self.b == other.b and self.c == other.c 

    def __ne__(self, other): 
     return not (self == other) 

    def __hash__(self): 
     return hash((self.a, self.b, self.c)) 

    def __repr__(self): 
     return '(%s, %s, %s)' % (self.a, self.b, self.c) 


item_cache = {} 
item_record = [] 


def process_item(new_item): 
    item = Item(*new_item) 
    try: 
     item_record.append(item_cache[item]) 
    except KeyError: 
     item_cache[item] = item 
     item_record.append(item) 

    del item # this happens anyway, just adding for clarity. 

for item in ((1, 2, 3), (2, 3, 4), (1, 2, 3), (2, 3, 4)): 
    process_item(item) 

print([id(item) for item in item_record]) 
print(item_record) 
+1

Wenn "Sache" unveränderlich ist (und es muss sein, oder Sie können es nicht als Schlüssel verwenden), ist vielleicht ein 'set()' ein besserer Container für den Cache? – DyZ

+0

Außerhalb des Kontexts, wird es besser sein, eine Eigenschaft von Object als Schlüssel 'item.some_unique_id' zu verwenden (kann Tupel/Composite anderer Eigenschaften sein) was ist bereits hashbar und hoffentlich unveränderlich? –

Antwort

3

Leider ja. Ein bisschen Überdenken in der Tat. Alles was Sie tun müssen, ist zu verwenden sets

Ein Set-Objekt ist eine ungeordnete Sammlung von verschiedenen hashable Objekte. Zu den gebräuchlichsten Anwendungen gehören das Testen von Mitgliedschaften, das Entfernen von Duplikaten aus einer Sequenz und das Berechnen mathematischer Operationen wie Schnittmenge, Vereinigung, Differenz und symmetrische Differenz.

Ihr Code kann mit

item_record = set() 
for .... : 
    item_record.add(input_item) 

Update ersetzt werden, obwohl Sie sagen „aber speichert nicht die gleichen Daten mehr als einmal“ Ihr Code tut tatsächlich speichert das Element mehr als eine. In Ihrem ursprünglichen Code, wird die item_record.append() Aufruf unabhängig davon ausgeführt werden, ob ein Element existiert in Itemcache

try: 
    item_record.append(item_cache[item]) 
except KeyError: 
    item_cache[item] = item # this is the part that seems weird 
    item_record.append(item) 

So wird die Liste Duplikate hat. Ich bin mir jedoch nicht ganz sicher, ob Sie die richtigen Objekte anhängen, weil Sie den Code für Ihre Item-Klasse nicht geteilt haben. Ich glaube, was wir wirklich haben, ist ein xy problem. Stellen Sie eine neue Frage und erklären Sie, was Sie zu lösen versuchen.

+0

was ist, wenn ich mehrere item_records habe? jeden Tag einen neuen, wenn ich einen neuen großen Teil der Eingabedaten erhalte. Ich möchte immer noch einen einzelnen Cache, aber ich kann nicht die gleiche Struktur für den Datensatz verwenden. – Ferguzz

+0

Ich verstehe Ihren Kommentar nicht – e4c5

+0

um, ok, aber ich denke, es ist besser, den Kommentar hier zu klären. – e4c5

Verwandte Themen