it-swarm.com.de

Wie vermeide ich den Fehler "RuntimeError: Größe des Dictionary während der Iteration geändert"

Ich habe alle anderen Fragen mit dem gleichen Fehler geprüft, aber keine hilfreiche Lösung gefunden = /

Ich habe ein Wörterbuch mit Listen:

d = {'a': [1], 'b': [1, 2], 'c': [], 'd':[]}

in denen einige Werte leer sind. Nach dem Erstellen dieser Listen möchte ich diese leeren Listen entfernen, bevor ich mein Wörterbuch zurücksende. Momentan versuche ich dies folgendermaßen zu tun:

for i in d:
    if not d[i]:
        d.pop(i)

dies gibt mir jedoch den Laufzeitfehler. Ich bin mir bewusst, dass Sie keine Elemente in einem Wörterbuch hinzufügen oder entfernen können, während Sie durchlaufen.

151
user1530318

In Python 2.x wird mit dem Aufruf von keys eine Kopie des Schlüssels erstellt, über die Sie während der Änderung von dict durchlaufen können:

for i in d.keys():

Beachten Sie, dass dies in Python 3.x nicht funktioniert, da keys einen Iterator anstelle einer Liste zurückgibt.

Eine andere Möglichkeit ist die Verwendung von list, um das Erstellen einer Kopie der Schlüssel zu erzwingen. Dieses funktioniert auch in Python 3.x:

for i in list(d):
293
Mark Byers

Verwenden Sie einfach das Wörterbuchverständnis, um die relevanten Elemente in ein neues Diktat zu kopieren

>>> d
{'a': [1], 'c': [], 'b': [1, 2], 'd': []}
>>> d = { k : v for k,v in d.iteritems() if v}
>>> d
{'a': [1], 'b': [1, 2]}
24
Maria Zverina

Sie müssen nur "Kopie" verwenden:

Auf diese Weise iterieren Sie über die ursprünglichen Wörterbuchfelder und können im Handumdrehen das gewünschte Diktat ändern (d dict) .

In [1]: d = {'a': [1], 'b': [1, 2], 'c': [], 'd':[]}

In [2]: for i in d.copy():
   ...:     if not d[i]:
   ...:         d.pop(i)
   ...:         

In [3]: d
Out[3]: {'a': [1], 'b': [1, 2]}
22
Alon Elharar

Ich würde versuchen, das Einfügen leerer Listen zu vermeiden, würde aber im Allgemeinen Folgendes verwenden:

d = {k: v for k,v in d.iteritems() if v} # re-bind to non-empty

Wenn vor 2.7:

d = dict( (k, v) for k,v in d.iteritems() if v )

oder nur:

empty_key_vals = list(k for k in k,v in d.iteritems() if v)
for k in empty_key_vals:
    del[k]
11
Jon Clements

Für Python 3:

{k:v for k,v in d.items() if v}
8
ucyo

Sie können ein Wörterbuch nicht durchlaufen, während es in der for-Schleife geändert wird. Erstellen Sie ein Casting, um es aufzulisten, und wiederholen Sie es, es funktioniert für mich.

    for key in list(d):
        if not d[key]: 
            d.pop(key)
1

Der Grund für den Laufzeitfehler ist, dass Sie eine Datenstruktur nicht durchlaufen können, während sich ihre Struktur während der Iteration ändert.

Eine Möglichkeit, das zu erreichen, wonach Sie suchen, besteht darin, die zu entfernenden Schlüssel mithilfe einer Liste anzufügen und dann die Pop-Funktion des Wörterbuchs zu verwenden, um den identifizierten Schlüssel zu entfernen, während Sie die Liste durchlaufen.

d = {'a': [1], 'b': [1, 2], 'c': [], 'd':[]}
pop_list = []

for i in d:
        if not d[i]:
                pop_list.append(i)

for x in pop_list:
        d.pop(x)
print (d)
0
Rohit

Für Situationen wie diese möchte ich eine tiefe Kopie machen und diese Kopie durchlaufen, während das ursprüngliche Diktat geändert wird.

Wenn sich das Suchfeld in einer Liste befindet, können Sie in der for-Schleife der Liste auflisten und dann die Position als Index angeben, um auf das Feld im ursprünglichen Diktat zuzugreifen.