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?

12voto

glihm Punkte 887

In Python 3 führt die Iteration von dic.keys() zu einem Fehler bei der Wörterbuchgröße. Sie können diesen alternativen Weg verwenden:

Getestet mit python3, es funktioniert gut und der Fehler " Größe des Wörterbuchs während der Iteration geändert " wird nicht erhoben:

my_dic = { 1:10, 2:20, 3:30 }
# Is important here to cast because ".keys()" method returns a dict_keys object.
key_list = list( my_dic.keys() )

# Iterate on the list:
for k in key_list:
    print(key_list)
    print(my_dic)
    del( my_dic[k] )

print( my_dic )
# {}

12voto

rsanden Punkte 1180

Es ist am saubersten zu benutzen list(mydict) :

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

Dies entspricht einer parallelen Struktur für Listen:

>>> mylist = ['one', 'two', 'three', 'four']
>>> for k in list(mylist):                            # or mylist[:]
...     if k == 'three':
...         mylist.remove(k)
... 
>>> mylist
['one', 'two', 'four']

Beide funktionieren in Python2 und Python3.

4voto

Pob Punkte 41

Sie könnten zunächst eine Liste der zu löschenden Schlüssel erstellen und dann diese Liste iterativ durchgehen, um sie zu löschen.

dict = {'one' : 1, 'two' : 2, 'three' : 3, 'four' : 4}
delete = []
for k,v in dict.items():
    if v%2 == 1:
        delete.append(k)
for i in delete:
    del dict[i]

3voto

Michal Charemza Punkte 24475

Es gibt einen Weg, der geeignet sein kann, wenn die zu löschenden Elemente immer am Anfang der Diktat-Iteration stehen

while mydict:
    key, value = next(iter(mydict.items()))
    if should_delete(key, value):
       del mydict[key]
    else:
       break

Der "Anfang" ist nur für bestimmte Python-Versionen/Implementierungen garantiert konsistent. Zum Beispiel von Was ist neu in Python 3.7

Die Erhaltung der Einfügereihenfolge von dict-Objekten wurde zu einem offiziellen Bestandteil der Python-Sprachbeschreibung erklärt.

Auf diese Weise wird eine Kopie des Diktats vermieden, die viele der anderen Antworten vorschlagen, zumindest in Python 3.

2voto

Jason Landbridge Punkte 589

Ich habe die oben genannten Lösungen in Python3 versucht, aber dies scheint die einzige zu sein, die für mich beim Speichern von Objekten in einem Diktat funktioniert. Im Grunde erstellen Sie eine Kopie Ihres dict() und iterieren darüber, während Sie die Einträge in Ihrem ursprünglichen Wörterbuch löschen.

        tmpDict = realDict.copy()
        for key, value in tmpDict.items():
            if value:
                del(realDict[key])

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