Ich weiß, dass ich einen Eintrag, 'Schlüssel' d
, sicher aus meinem Wörterbuch entfernen muss.
if d.has_key('key'):
del d['key']
Ich muss jedoch mehrere Einträge sicher aus dem Wörterbuch entfernen. Ich habe darüber nachgedacht, die Einträge in einem Tupel zu definieren, da ich dies mehr als einmal tun muss.
entitiesToREmove = ('a', 'b', 'c')
for x in entitiesToRemove:
if d.has_key(x):
del d[x]
Ich habe mich jedoch gefragt, ob es einen intelligenteren Weg gibt, dies zu tun.
python
dictionary
dublintech
quelle
quelle
key in d
ist mehr pythonisch alsd.has_key(key)
stackoverflow.com/questions/1323410/has-key-or-infor x in set(d) & entities_to_remove: del d[x]
. Dies wird wahrscheinlich nur dann effizienter sein, wennentities_to_remove
es "groß" ist.Antworten:
Warum nicht so:
Eine kompaktere Version wurde von mattbornski mit dict.pop () bereitgestellt
quelle
del dict['key1'], dict['key2'], dict['key3']
for key in set(the_dict) & entries:
denkey in dict
Test zu verwenden und zu umgehen .quelle
dict.pop()
macht das Testen der Schlüsselexistenz überflüssig. Ausgezeichnet..pop()
schlecht und unpythonisch und würde die akzeptierte Antwort dieser vorziehen.setdefault
. Bei korrekter Implementierung (und ich bin mir sicher, dass dies der Fall ist) wird nur eine Suche in der Hash-Map durchgeführt, dh diedict
anstelle von zwei.Verwenden von Diktatverständnissen
wo Schlüssel1 und Schlüssel2 entfernt werden sollen.
Im folgenden Beispiel müssen die Schlüssel "b" und "c" entfernt und in einer Schlüsselliste gespeichert werden.
quelle
O(n)
. Die gesamte Operation besteht darinO(mn)
, wom
sich die Anzahl der Schlüssel im Diktat undn
die Anzahl der Schlüssel in der Liste befinden. Ich schlage vor{key1, key2}
, wenn möglich stattdessen ein Set zu verwenden.Eine Lösung verwendet
map
undfilter
funktioniertPython 2
Python 3
du erhältst:
quelle
>>> d={"a":1,"b":2,"c":3} >>> l=("a","b","d") >>> map(d.__delitem__, filter(d.__contains__,l)) <map object at 0x10579b9e8> >>> print(d) {'a': 1, 'b': 2, 'c': 3}
list(map(d.__delitem__,filter(d.__contains__,l)))
.... in Python 3.4 Map-Funktion einen Iterator zurückgebendeque(map(...), maxlen=0)
zu vermeiden, dass eine Liste mit None-Werten erstellt wird; erster Import mitfrom collections import deque
Wenn Sie auch die Werte für die Schlüssel abrufen müssen, die Sie entfernen, ist dies ein guter Weg, dies zu tun:
Sie könnten dies natürlich immer noch nur zum Entfernen der Schlüssel aus tun
d
, aber Sie würden unnötigerweise die Werteliste mit dem Listenverständnis erstellen. Es ist auch ein wenig unklar, ein Listenverständnis nur für die Nebenwirkung der Funktion zu verwenden.quelle
valuesRemoved = dict((k, d.pop(k, None)) for k in entitiesToRemove)
und so weiter.Mit
pop
und eine Lösung gefundenmap
Die Ausgabe davon:
Ich habe diese Frage so spät beantwortet, nur weil ich denke, dass es in Zukunft helfen wird, wenn jemand dasselbe sucht. Und das könnte helfen.
Aktualisieren
Der obige Code löst einen Fehler aus, wenn im Diktat kein Schlüssel vorhanden ist.
Ausgabe:
quelle
keys
löst eine Ausnahme aus, wenn kein Schlüssel in vorhanden istd
- Sie müssten diesen zuerst filtern.Ich habe kein Problem mit einer der vorhandenen Antworten, aber ich war überrascht, diese Lösung nicht zu finden:
Hinweis: Ich bin auf diese Frage gestoßen, die von hier kommt . Und meine Antwort bezieht sich auf diese Antwort .
quelle
Warum nicht:
Ich weiß nicht, was du mit "klügerer Weg" meinst. Sicher gibt es andere Möglichkeiten, vielleicht mit Wörterbuchverständnis:
quelle
in der Reihe
quelle
Einige Timing-Tests für cpython 3 zeigen, dass eine einfache for-Schleife der schnellste Weg ist und gut lesbar ist. Das Hinzufügen einer Funktion verursacht auch nicht viel Overhead:
Timeit-Ergebnisse (10.000 Iterationen):
all(x.pop(v) for v in r) # 0.85
all(map(x.pop, r)) # 0.60
list(map(x.pop, r)) # 0.70
all(map(x.__delitem__, r)) # 0.44
del_all(x, r) # 0.40
<inline for loop>(x, r) # 0.35
Bei kleinen Iterationen war dies aufgrund des Overheads des Funktionsaufrufs etwas schneller. Aber
del_all
ist fusselsicher, wiederverwendbar und schneller als alle Python-Verständnis- und Mapping-Konstrukte.quelle
Ich denke, die Tatsache, dass die Schlüssel als Set behandelt werden können, ist der schönste Weg, wenn Sie mit Python 3 arbeiten:
Beispiel:
quelle
Es wäre schön, volle Unterstützung für festgelegte Methoden für Wörterbücher zu haben (und nicht für das unheilige Durcheinander, das wir mit Python 3.9 bekommen), damit Sie einfach einen Satz von Schlüsseln "entfernen" können. Solange dies jedoch nicht der Fall ist und Sie ein großes Wörterbuch mit möglicherweise einer großen Anzahl von Schlüsseln zum Entfernen haben, möchten Sie möglicherweise Informationen zur Leistung erhalten. Also habe ich einen Code erstellt, der etwas erstellt, das groß genug für aussagekräftige Vergleiche ist: eine 100.000 x 1000-Matrix, also insgesamt 10.000,00 Elemente.
10 Millionen Artikel oder mehr sind in einigen Einstellungen nicht ungewöhnlich. Beim Vergleich der beiden Methoden auf meinem lokalen Computer sehe ich eine leichte Verbesserung bei der Verwendung
map
undpop
vermutlich aufgrund weniger Funktionsaufrufe, aber beide dauern auf meinem Computer ungefähr 2,5 Sekunden. Dies verblasst jedoch im Vergleich zu der Zeit, die erforderlich ist, um das Wörterbuch überhaupt zu erstellen (55 Sekunden) oder Überprüfungen in die Schleife einzubeziehen. Wenn dies wahrscheinlich ist, erstellen Sie am besten eine Menge, die eine Schnittstelle zwischen den Wörterbuchschlüsseln und Ihrem Filter darstellt:keys = cells.keys() & keys
Zusammenfassend:
del
ist bereits stark optimiert, machen Sie sich also keine Sorgen über die Verwendung.quelle
Ich bin zu spät zu dieser Diskussion, aber für alle anderen. Eine Lösung kann darin bestehen, eine Liste von Schlüsseln als solche zu erstellen.
Verwenden Sie dann pop () in einem Listenverständnis oder eine for-Schleife, um die Tasten zu durchlaufen und einzeln als solche zu popen.
Das 'n / a' ist, falls der Schlüssel nicht existiert, muss ein Standardwert zurückgegeben werden.
quelle
new_dictionary
sieht sehr nach einer Liste aus;)