Ich bin neu in Python und mit der Implementierung von Multimaps in anderen Sprachen vertraut . Ist in Python eine solche Datenstruktur integriert oder in einer häufig verwendeten Bibliothek verfügbar?
Um zu veranschaulichen, was ich mit "Multimap" meine:
a = multidict()
a[1] = 'a'
a[1] = 'b'
a[2] = 'c'
print(a[1]) # prints: ['a', 'b']
print(a[2]) # prints: ['c']
python
dictionary
James Bond
quelle
quelle
a[1] = 'b'
des Anhängens an eine [1] ist für Benutzer, die diesen Code lesen oder pflegen, verwirrend. Ich würde empfehlen, dies nicht in Python zu tun.Antworten:
So etwas ist in der Standardbibliothek nicht vorhanden. Sie können ein
defaultdict
obwohl verwenden:>>> from collections import defaultdict >>> md = defaultdict(list) >>> md[1].append('a') >>> md[1].append('b') >>> md[2].append('c') >>> md[1] ['a', 'b'] >>> md[2] ['c']
(Anstelle von
list
möchten Sie möglicherweise verwendenset
, in welchem Fall Sie.add
anstelle von anrufen würden.append
.)Nebenbei : Sehen Sie sich diese beiden Zeilen an, die Sie geschrieben haben:
a[1] = 'a' a[1] = 'b'
Dies scheint darauf hinzudeuten, dass der Ausdruck
a[1]
zwei unterschiedlichen Werten entsprechen soll. Dies ist bei Wörterbüchern nicht möglich, da ihre Schlüssel eindeutig sind und jeder von ihnen einem einzelnen Wert zugeordnet ist. Sie können jedoch nacheinander alle Werte in der Liste extrahieren, die einem bestimmten Schlüssel zugeordnet sind. Sie können dafüriter
gefolgt von aufeinanderfolgenden Aufrufen verwendennext
. Oder Sie können einfach zwei Schleifen verwenden:>>> for k, v in md.items(): ... for w in v: ... print("md[%d] = '%s'" % (k, w)) ... md[1] = 'a' md[1] = 'b' md[2] = 'c'
quelle
Nur für zukünftige Besucher. Derzeit gibt es eine Python-Implementierung von Multimap. Es ist über Pypi erhältlich
quelle
defaultdict(set)
?Stephan202 hat die richtige Antwort, benutze
defaultdict
. Wenn Sie jedoch etwas mit der Schnittstelle von C ++ STL Multimap und einer viel schlechteren Leistung wünschen, können Sie dies tun:multimap = [] multimap.append( (3,'a') ) multimap.append( (2,'x') ) multimap.append( (3,'b') ) multimap.sort()
Wenn Sie jetzt durchlaufen
multimap
, erhalten Sie Paare wie in einemstd::multimap
. Leider bedeutet dies, dass Ihr Schleifencode so hässlich aussieht wie C ++.def multimap_iter(multimap,minkey,maxkey=None): maxkey = minkey if (maxkey is None) else maxkey for k,v in multimap: if k<minkey: continue if k>maxkey: break yield k,v # this will print 'a','b' for k,v in multimap_iter(multimap,3,3): print v
Zusammenfassend
defaultdict
ist es wirklich cool und nutzt die Kraft von Python und Sie sollten es verwenden.quelle
Sie können eine Liste von Tupeln erstellen und diese dann sortieren, als wäre es eine Multimap.
Fügen wir einige Elemente (Tupel) hinzu:
listAsMultimap.append((1,'a')) listAsMultimap.append((2,'c')) listAsMultimap.append((3,'d')) listAsMultimap.append((2,'b')) listAsMultimap.append((5,'e')) listAsMultimap.append((4,'d'))
Jetzt sortiere es.
Nach dem Drucken erhalten Sie:
[(1, 'a'), (2, 'b'), (2, 'c'), (3, 'd'), (4, 'd'), (5, 'e')]
Das heißt, es funktioniert als Multimap!
Bitte beachten Sie, dass wie bei Multimap hier auch Werte in aufsteigender Reihenfolge sortiert werden, wenn die Schlüssel gleich sind (für Schlüssel = 2 steht 'b' vor 'c', obwohl wir sie nicht in dieser Reihenfolge angehängt haben.)
Wenn Sie sie in absteigender Reihenfolge erhalten möchten, ändern Sie einfach die Funktion sortiert () wie folgt:
listAsMultimap=sorted(listAsMultimap,reverse=True)
Und nachdem Sie folgende Ausgabe erhalten haben:
[(5, 'e'), (4, 'd'), (3, 'd'), (2, 'c'), (2, 'b'), (1, 'a')]
In ähnlicher Weise sind hier die Werte in absteigender Reihenfolge, wenn die Schlüssel gleich sind.
quelle
Die Standardmethode zum Schreiben in Python ist ein Diktat, dessen Elemente jeweils ein
list
oder sindset
. Wie stephan202 sagt , können Sie dies mit einem Standarddikt etwas automatisieren, müssen es aber nicht.Mit anderen Worten, ich würde Ihren Code in übersetzen
a = dict() a[1] = ['a', 'b'] a[2] = ['c'] print(a[1]) # prints: ['a', 'b'] print(a[2]) # prints: ['c']
quelle
a[1] = 'b'
als Anhängen zu behandeln, anstatt es zu ersetzena[1]
.Oder Unterklasse
dict
:class Multimap(dict): def __setitem__(self, key, value): if key not in self: dict.__setitem__(self, key, [value]) # call super method to avoid recursion else self[key].append(value)
quelle
Derzeit gibt es in den Python-Standardbibliotheken keine Multi-Map.
WebOb verfügt über eine MultiDict- Klasse, die zur Darstellung von HTML-Formularwerten verwendet wird. Sie wird von einigen Python-Webframeworks verwendet, sodass die Implementierung kampferprobt ist.
Aus dem gleichen Grund hat Werkzeug auch eine MultiDict- Klasse.
quelle
Ich verstehe die Semantik Ihres Beispiels nicht klar
a[1] = 'a' a[1] = 'b' #??
Soll die zweite Zeile
a[1] = 'b'
das Element bei [1] ersetzen? Wenn ja, müssen Sie ein Wörterbuch verwenden. Wenn nicht, müssen Sie ein Listenwörterbuch verwenden (wie bereits vorgeschlagen).quelle