2016-04-20 12 views
0

Ich verwende Tupel als Schlüssel für ein Wörterbuch, das ich erstellt habe. Zum Beispiel:Wie man die Reihenfolge der Elemente in einem Tupel ignoriert

example_dict = {} 
example_dict[("A", "B")] = "1" 

Später, als ich den Wert eines Eintrags im Wörterbuch ändern wollen habe ich nicht noch Kontrolle über die Reihenfolge des Tupels. Zum Beispiel:

("B", "A") may be the case, instead of ("A", "B") 

Ich bin mir bewusst, dass diese Tupel nicht gleich von einem einfachen == Vergleich ist, dass ich in dem Python-Shell versucht.

Was ich frage mich ist, wie ich das umgehen könnte? Wie könnte ich das folgende keine KeyError produzieren:

print (example_dict["B", "A"]) 

Gibt es eine Möglichkeit konsequent, um die Elemente eines Tupels bestellen? Gibt es eine Möglichkeit, die Reihenfolge vollständig zu ignorieren? Irgendwelche anderen Arbeiten um? Ich bin mir bewusst, dass ich einfach alle Tupel-Arrangements als Schlüssel in das Dictionary aufnehmen und dann die Werte der verschiedenen Permutationen später zusammentragen könnte. Ich möchte dies unbedingt vermeiden, da dies dem Problem nur Schwierigkeiten und Komplexität hinzufügt.

Antwort

4

Sie möchten, dass Ihre Wörterbuchschlüssel "Sätze" sind (ein Satz ist eine Sammlung, für die ein Artikel entweder im Satz enthalten ist oder nicht, der aber kein Ordnungskonzept hat). Zum Glück hat Python was Sie brauchen. Insbesondere, weil Sie etwas hashable brauchen, das Sie verwenden möchten frozenset.

>>> example_dict = {} 
>>> example_dict[frozenset(("A", "B"))] = "1" 
>>> example_dict[frozenset(("B", "A"))] 
'1' 
>>> example_dict[frozenset(("A", "B"))] 
'1' 
+0

Sets haben auch kein Konzept der Elementmultiplizität. Das spielt keine Rolle, wenn Ihre Tupel alle die Länge 2 haben, aber es kann unordentlich zerbrechen, wenn Sie drei Elemente haben und Sie nicht unterscheiden können ("A", "A", "B") "from" ("A" , "B", "B") ", oder wenn Ihre Tupel unterschiedliche Längen haben können und Sie' ("A", "' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Es bricht auch, wenn Sie versuchen, etwas wie "für ein, b in example_dict" zu tun. – user2357112

+0

Irgendein Kommentar zur Effizienz dieses? Es scheint, dass 'Frozenset's viel größer sind als 'Tuple's, was die Speichergröße betrifft. – sudo

2

Statt eine tuple verwenden, verwenden Sie einen frozenset. Eine frozenset ist nur eine Konstante set, genauso wie eine tuple kann als eine Konstante list gedacht werden.

Hier ist ein Beispiel (aus Python 3, aber es wird in Python 2 so gut funktionieren):

>>> d = {} 
>>> k1 = frozenset((1, 2)) 
>>> k2 = frozenset((2, 1)) 
>>> k1 
frozenset({1, 2}) 
>>> k2 
frozenset({1, 2}) 
>>> k1 == k2 
True 
>>> d[k1] = 123 
>>> d[k2] 
123 
>>> 
5

die übliche Art und Weise sind die Schlüssel entweder sortieren:

example_dict[tuple(sorted(key_tuple))] = "1" 

Verwendung frozensets als Tasten (wenn es nicht sein, doppelte Elemente in den Tupeln):

example_dict[frozenset(key_tuple)] = "1" 

oder frozensets von (item, count) verwenden Tupel als Schlüssel (wenn es können doppelte Elemente in den Tupeln sein):

example_dict[frozenset(Counter(key_tuple).viewitems())] = "1" 

Unabhängig davon, welche Variante Sie sich entscheiden, Sie haben die gleiche Transformation anwenden, wenn Sie Werte nachschlagen.

Verwandte Themen