439 Stimmen

Wie kann man Elemente aus einem Wörterbuch löschen, während man über sie iteriert?

Ist es legitim, Elemente aus einem Wörterbuch in Python zu löschen, während Iteration über sie?

Zum Beispiel:

for k, v in mydict.iteritems():
    if k == val:
        del mydict[k]

Die Idee ist, Elemente, die eine bestimmte Bedingung nicht erfüllen, aus dem Wörterbuch zu entfernen, anstatt ein neues Wörterbuch zu erstellen, das eine Teilmenge des Wörterbuchs ist, über das iteriert wird.

Ist dies eine gute Lösung? Gibt es elegantere/effizientere Möglichkeiten?

440voto

Blair Punkte 14382

EDIT:

Für Python3 (oder höher):

>>> mydict
{'four': 4, 'three': 3, 'one': 1}

>>> for k in list(mydict.keys()):
...     if mydict[k] == 3:
...         del mydict[k]
...
>>> mydict
{'four': 4, 'one': 1}

Der Rest der Antworten funktioniert gut mit Python2 arbeiten aber nicht für Python3 und erhebt RuntimeError .

RuntimeError: Wörterbuch hat Größe während Iteration geändert.

Dies geschieht, weil mydict.keys() gibt einen Iterator und keine Liste zurück. Wie in den Kommentaren erwähnt, konvertieren Sie einfach mydict.keys() zu einer Liste von list(mydict.keys()) und es sollte funktionieren.


Für python2 :

Ein einfacher Test in der Konsole zeigt, dass Sie ein Wörterbuch nicht ändern können, während Sie darüber iterieren:

>>> mydict = {'one': 1, 'two': 2, 'three': 3, 'four': 4}
>>> for k, v in mydict.iteritems():
...    if k == 'two':
...        del mydict[k]
...
------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
RuntimeError: dictionary changed size during iteration

Wie in der Antwort von delnan erwähnt, verursacht das Löschen von Einträgen Probleme, wenn der Iterator versucht, zum nächsten Eintrag zu gelangen. Verwenden Sie stattdessen die keys() Methode, um eine Liste der Schlüssel zu erhalten und mit dieser zu arbeiten:

>>> for k in mydict.keys():
...    if k == 'two':
...        del mydict[k]
...
>>> mydict
{'four': 4, 'three': 3, 'one': 1}

Wenn Sie auf der Grundlage des Elementwerts löschen müssen, verwenden Sie die items() Methode:

>>> for k, v in mydict.items():
...     if v == 3:
...         del mydict[k]
...
>>> mydict
{'four': 4, 'one': 1}

118voto

Jochen Ritzel Punkte 99416

Sie können es auch in zwei Schritten machen:

remove = [k for k in mydict if k == val]
for k in remove: del mydict[k]

Mein bevorzugter Ansatz ist normalerweise, einfach ein neues Diktat zu erstellen:

# Python 2.7 and 3.x
mydict = { k:v for k,v in mydict.items() if k!=val }
# before Python 2.7
mydict = dict((k,v) for k,v in mydict.iteritems() if k!=val)

35voto

Iterieren Sie stattdessen über eine Kopie, wie die, die von items() :

for k, v in list(mydict.items()):

27voto

Sie können eine Sammlung während der Iteration nicht ändern. Dieser Weg führt in den Wahnsinn - vor allem, wenn Sie das aktuelle Element löschen dürfen, müsste der Iterator weitergehen (+1) und der nächste Aufruf von next würde über diesen Wert hinausgehen (+2), so dass ein Element übersprungen würde (das Element direkt hinter dem gelöschten). Sie haben zwei Möglichkeiten:

  • Kopieren Sie alle Schlüssel (oder Werte oder beides, je nachdem, was Sie brauchen), und führen Sie dann eine Iteration über diese durch. Sie können .keys() et al. (in Python 3 übergeben Sie den resultierenden Iterator an list ). Das könnte allerdings sehr platzraubend sein.
  • Iterieren über mydict wie üblich, wobei die zu löschenden Schlüssel in einer separaten Sammlung gespeichert werden to_delete . Wenn Sie mit der Iteration fertig sind mydict löschen Sie alle Einträge in to_delete de mydict . Spart etwas (je nachdem, wie viele Schlüssel gelöscht werden und wie viele bleiben) Platz gegenüber dem ersten Ansatz, erfordert aber auch ein paar Zeilen mehr.

14voto

Aaron Punkte 101

Sie können ein Wörterbuch zum Verständnis verwenden.

d = {k:d[k] for k in d if d[k] != val}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X