Hoe de fout “RuntimeError: woordenboek veranderde grootte tijdens iteratie” vermijden?

Ik heb alle andere vragen met dezelfde fout gecontroleerd, maar heb geen nuttige oplossing gevonden =/

Ik heb een woordenboek met lijsten:

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

waarin sommige waarden leeg zijn. Aan het einde van het maken van deze lijsten, wil ik deze lege lijsten verwijderen voordat ik mijn woordenboek teruggeef. Momenteel probeer ik dit als volgt te doen:

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

dit geeft me echter de runtime-fout. Ik ben me ervan bewust dat je geen elementen in een woordenboek kunt toevoegen/verwijderen terwijl je het doorloopt…wat zou dan een manier zijn om dit te omzeilen?


Antwoord 1, autoriteit 100%

In Python 3.x en 2.x kun je gebruik maken van listom een kopie van de sleutels te forceren:

for i in list(d):

In Python 2.x aanroepen van keysmaakte een kopie van de sleutels die je kon herhalen terwijl je het dictaanpaste:

for i in d.keys():

Maar merk op dat in Python 3.x deze tweede methode niet helpt bij je fout omdat keyseen view objectin plaats van de sleutels naar een lijst te kopiëren.


Antwoord 2, autoriteit 13%

U hoeft alleen “copy” te gebruiken:

Op die manier herhaal je de originele woordenboekvelden en kun je direct het gewenste dict (d dict) wijzigen.
Het is werk op elke python-versie, dus het is duidelijker.

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]}

Antwoord 3, autoriteit 9%

Gebruik gewoon woordenboekbegrip om de relevante items naar een nieuw dictaat te kopiëren

>>> 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]}

Hiervoor in Python 3

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

Antwoord 4, autoriteit 3%

Dit werkte voor mij:

dict = {1: 'a', 2: '', 3: 'b', 4: '', 5: '', 6: 'c'}
for key, value in list(dict.items()):
    if (value == ''):
        del dict[key]
print(dict)
# dict = {1: 'a', 3: 'b', 6: 'c'}  

Door de woordenboekitems naar de lijst te casten, wordt een lijst met de bijbehorende items gemaakt, zodat u deze kunt herhalen en de RuntimeErrorkunt vermijden.


Antwoord 5, autoriteit 2%

Ik zou in de eerste plaats proberen om het invoegen van lege lijsten te vermijden, maar zou over het algemeen het volgende gebruiken:

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

Indien vóór 2.7:

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

of alleen:

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

Antwoord 6, Autoriteit 2%

Voor Python 3:

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

Antwoord 7

U kunt niet door een Woordenboek herhalen terwijl het tijdens de lus verandert. Maak een gietstuk om te vermelden en te itereren over die lijst, het werkt voor mij.

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

Antwoord 8

De reden voor de runtime-fout is dat u niet via een gegevensstructuur kunt herhalen, terwijl de structuur tijdens het iteratie verandert.

Een manier om te bereiken waarnaar u op zoek bent, is om de lijst te gebruiken om de toetsen toe te voegen die u wilt verwijderen en vervolgens POP-functie op het woordenboek gebruiken om de geïdentificeerde toets te verwijderen terwijl u herhoogt.

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)

Antwoord 9

Python 3 staat geen verwijdering toe terwijl het herformeert (met behulp van voor lus hierboven) woordenboek. Er zijn verschillende alternatieven om te doen; Een eenvoudige manier is om de volgende regel

te wijzigen

for i in x.keys():

met

for i in list(x)

Antwoord 10

dictc={"stName":"asas"}
keys=dictc.keys()
for key in list(keys):
    dictc[key.upper()] ='New value'
print(str(dictc))

Antwoord 11

Om te voorkomen dat “Woordenboek wordt gewijzigd in de iteratiefout”
Gebruik gewoon ‘Lijst’ met ‘.items ()’ en hier is een eenvoudig voorbeeld:

my_dict = {
    'k1':1,
    'k2':2,
    'k3':3,
    'k4':4
    }
print(my_dict)
for key, val in list(my_dict.items()):
    if val == 2 or val == 4:
        my_dict.pop(key)
print(my_dict)

+++
OUTPUT:

{‘k1’: 1, ‘k2’: 2, ‘k3’: 3, ‘k4’: 4}

{‘k1’: 1, ‘k3’: 3}

+++

Dit is gewoon voorbeeld en verandert het op basis van uw zaak / vereisten,
Ik hoop dat dit nuttig is.


Antwoord 12

Voor situaties zoals dit, hou ik ervan om een ​​diepe kopie en lus door die kopie te maken tijdens het wijzigen van het originele dict.

Als het opzoekveld zich binnen een lijst bevindt, kunt u in de lus van de lijst opsluiten en vervolgens de positie als index opgeven om toegang te krijgen tot het veld in de originele dict.

Other episodes