Wie kann ich in Python das Wörterbuch durchlaufen und den Wert ändern, wenn er etwas entspricht?

75

Wenn der Wert None ist, möchte ich ihn in "" (leere Zeichenfolge) ändern.

Ich fange so an, aber ich vergesse:

for k, v in mydict.items():
    if v is None:
... right?
TIMEX
quelle

Antworten:

137
for k, v in mydict.iteritems():
    if v is None:
        mydict[k] = ''

In einem allgemeineren Fall, z. B. wenn Sie Schlüssel hinzufügen oder entfernen, ist es möglicherweise nicht sicher, die Struktur des Containers zu ändern, in dem Sie sich itemsin einer Schleife befinden. Daher ist es möglicherweise ratsam, eine unabhängige Listenkopie davon zu durchlaufen Das Zuweisen eines anderen Werts zu einem bestimmten vorhandenen Index ist kein Problem. In Python 2.any ist es daher besser, ihn zu verwenden iteritems.

In Python3 gibt der Code jedoch einen AttributeError: 'dict' object has no attribute 'iteritems'Fehler aus. Verwenden Sie items()statt iteritems()hier.

Siehe diesen Beitrag.

Alex Martelli
quelle
1
@ John, es gilt für jeden eingebauten Container - genauso für eine Liste wie für ein Diktat - und ich denke, "Index" ist ein allgemeinerer Begriff als "Schlüssel".
Alex Martelli
2
mydict[k] = ''- Ihr Beispiel aktualisiert den kIndex auf ein unveränderliches Objekt ''. Also kwürde danach auf ein ganz anderes Objekt verweisen als v. Würde dies den kIndex auf irgendeine Weise mutieren, die Probleme mit verursachen könnte .iteritems()?
CivFan
4
@CivFan, nein, das Ändern oder Neuzuweisen eines Werts (im Gegensatz zu einem Schlüssel ) gibt keine Probleme mit dict.iteritems.
Alex Martelli
Hmm ... Ich frage mich, ob der Ratschlag zum .itemsSchleifen beim Hinzufügen / Entfernen von Schlüsseln umsichtig ist. Ich kenne die Implementierungsdetails von dict_itemsObjekten nicht, aber es scheint, dass Sie immer noch Probleme haben, diese in python3.x zu durchlaufen, wenn Sie Schlüssel hinzufügen / löschen. In diesem Fall ist es wahrscheinlich am sichersten, eine Liste der Schlüssel zu for k in list(mydict): v = mydict[k]; ...
durchlaufen
15

Sie können ein Diktatverständnis nur für die Elemente erstellen, deren Werte Keine sind, und dann wieder auf das Original aktualisieren:

tmp = dict((k,"") for k,v in mydict.iteritems() if v is None)
mydict.update(tmp)

Update - hat einige Leistungstests durchgeführt

Nun, nachdem Sie Diktate von 100 bis 10.000 Elementen mit unterschiedlichem Prozentsatz von None-Werten ausprobiert haben, ist die Leistung von Alex 'Lösung auf der ganzen Linie ungefähr doppelt so schnell wie die dieser Lösung.

PaulMcG
quelle
Hmm, für Python 2.7 sehe ich ungefähr die gleiche Leistung (obwohl die Alex-Methode immer noch schneller ist); Ich habe Diktate mit 1000 .. 100000 Werten und keinem Prozentsatz von 2 bis 50 %% ausprobiert; Zum Vergleich war die Methode von Buckley (mit s / items / iteritems /) etwa viermal langsamer. Ich denke, das ist irgendwie interessant, da Ihr Formular es einem ermöglicht, das Wörterbuch bei der Iteration zu ändern.
ョ ー ジ
9

Das Verständnis ist normalerweise schneller, und dies hat den Vorteil, dass es mydictwährend der Iteration nicht bearbeitet wird:

mydict = dict((k, v if v else '') for k, v in mydict.items())
Buckley
quelle
Wenn Sie es verwenden, spielt .items()es keine Rolle (für Python2), ob Sie Änderungen vornehmen, mydictda sich die Liste, die .items()zurückgegeben wird, nicht ändert, selbst wenn Sie Schlüssel vonmydict
John La Rooy
4
Das Ändern nur von Werten in einem Diktat ist niemals ein Problem. Trauer wird durch Hinzufügen / Löschen von Schlüsseln verursacht, während über das Diktat iteriert wird. Verständnis ist schneller als WAS? Wirklich schnell: Kopieren des gesamten Diktats, wenn ein oder zwei Nones geändert werden müssen. Apropos Nones, sollten Sie if v is not Nonestattdessen haben if v(lesen Sie die Frage erneut). Gesamtübersicht: -1
John Machin
Ihre Lösung ersetzt 0, leere Liste und alles, was in einem booleschen Kontext falsch ist, durch ''. Ich würde vorschlagen, if vdurch zu ersetzen if v is None, dies ist auch PEP 8-konformer: python.org/dev/peps/pep-0008/#programming-recommendations
Statistic Dean