Dictionary changed size during iteration как исправить

I have a dictionary of lists in which some of the values are empty:

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

At the end of creating these lists, I want to remove these empty lists before returning my dictionary. I tried doing it like this:

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

but I got a RuntimeError. I am aware that you cannot add/remove elements in a dictionary while iterating through it…what would be a way around this then?


See Modifying a Python dict while iterating over it for citations that this can cause problems, and why.

Peter Mortensen's user avatar

asked Aug 13, 2012 at 20:30

user1530318's user avatar

1

In Python 3.x and 2.x you can use use list to force a copy of the keys to be made:

for i in list(d):

In Python 2.x calling .keys made a copy of the keys that you could iterate over while modifying the dict:

for i in d.keys():

but on Python 3.x, .keys returns a view object instead, so it won’t fix your error.

Boris Verkhovskiy's user avatar

answered Aug 13, 2012 at 20:33

Mark Byers's user avatar

Mark ByersMark Byers

805k190 gold badges1576 silver badges1450 bronze badges

7

You only need to use copy:

This way you iterate over the original dictionary fields and on the fly can change the desired dict d.
It works on each Python version, so it’s more clear.

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

(BTW — Generally to iterate over copy of your data structure, instead of using .copy for dictionaries or slicing [:] for lists, you can use import copy -> copy.copy (for shallow copy which is equivalent to copy that is supported by dictionaries or slicing [:] that is supported by lists) or copy.deepcopy on your data structure.)

mkrieger1's user avatar

mkrieger1

18.2k4 gold badges53 silver badges64 bronze badges

answered Mar 31, 2016 at 10:35

Alon Elharar's user avatar

Alon ElhararAlon Elharar

1,2291 gold badge8 silver badges3 bronze badges

1

Just use dictionary comprehension to copy the relevant items into a new dict:

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

For this in Python 2:

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

Peter Mortensen's user avatar

answered Aug 13, 2012 at 20:38

Maria Zverina's user avatar

Maria ZverinaMaria Zverina

10.8k3 gold badges44 silver badges61 bronze badges

3

This worked for me:

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

Casting the dictionary items to list creates a list of its items, so you can iterate over it and avoid the RuntimeError.

wjandrea's user avatar

wjandrea

27.1k9 gold badges58 silver badges80 bronze badges

answered Jan 31, 2020 at 9:05

singrium's user avatar

singriumsingrium

2,6645 gold badges30 silver badges45 bronze badges

0

To avoid «dictionary changed size during iteration error».

For example: «when you try to delete some key»,

Just use ‘list’ with ‘.items()’. Here is a simple example:

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}

This is just an example. Change it based on your case/requirements.

Peter Mortensen's user avatar

answered Mar 19, 2021 at 22:59

K.A's user avatar

K.AK.A

1,26111 silver badges21 bronze badges

1

I would try to avoid inserting empty lists in the first place, but, would generally use:

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

If prior to 2.7:

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

or just:

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

answered Aug 13, 2012 at 20:42

Jon Clements's user avatar

Jon ClementsJon Clements

138k32 gold badges244 silver badges278 bronze badges

5

For Python 3:

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

Ahmad's user avatar

Ahmad

2273 silver badges15 bronze badges

answered Jan 14, 2016 at 16:14

ucyo's user avatar

ucyoucyo

6177 silver badges16 bronze badges

1

You cannot iterate through a dictionary while it’s changing during a for loop. Make a casting to list and iterate over that list. It works for me.

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

Peter Mortensen's user avatar

answered May 17, 2019 at 9:28

Alvaro Romero Diaz's user avatar

Python 3 does not allow deletion while iterating (using the for loop above) a dictionary. There are various alternatives to do it; one simple way is to change the line

for i in x.keys():

with

for i in list(x)

Peter Mortensen's user avatar

answered Dec 26, 2019 at 22:23

Hasham Beyg's user avatar

Hasham BeygHasham Beyg

3153 silver badges11 bronze badges

0

The reason for the runtime error is that you cannot iterate through a data structure while its structure is changing during iteration.

One way to achieve what you are looking for is to use a list to append the keys you want to remove and then use the pop function on dictionary to remove the identified key while iterating through the list.

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)

Peter Mortensen's user avatar

answered Oct 6, 2018 at 21:00

Rohit's user avatar

RohitRohit

173 bronze badges

For situations like this, I like to make a deep copy and loop through that copy while modifying the original dict.

If the lookup field is within a list, you can enumerate in the for loop of the list and then specify the position as the index to access the field in the original dict.

Peter Mortensen's user avatar

answered Oct 30, 2018 at 20:41

Ajayi Oluwaseun Emmanuel's user avatar

0

  • The Python «RuntimeError: dictionary changed size during iteration» occurs when we change the size of a dictionary when iterating over it.

  • To solve the error, use the copy() method to create a shallow copy of the dictionary that you can iterate over, e.g., my_dict.copy().

    my_dict = {'a': 1, 'b': 2, 'c': 3}
    
    for key in my_dict.copy():
        print(key)
        if key == 'b':
            del my_dict[key]
    
    print(my_dict) # 👉️ {'a': 1, 'c': 3}
    
  • You can also convert the keys of the dictionary to a list and iterate over the list of keys.

    my_dict = {'a': 1, 'b': 2, 'c': 3}
    
    for key in list(my_dict.keys()):
        print(key)
        if key == 'b':
            del my_dict[key]
    
    print(my_dict)  # 👉️ {'a': 1, 'c': 3}
    

Peter Mortensen's user avatar

answered Dec 6, 2022 at 22:11

Md Shayon's user avatar

Nested null values

Let’s say we have a dictionary with nested keys, some of which are null values:

dicti = {
"k0_l0":{
    "k0_l1": {
        "k0_l2": {
                "k0_0":None,
                "k1_1":1,
                "k2_2":2.2
                }
        },
        "k1_l1":None,
        "k2_l1":"not none",
        "k3_l1":[]
    },
    "k1_l0":"l0"
}

Then we can remove the null values using this function:

def pop_nested_nulls(dicti):
    for k in list(dicti):
        if isinstance(dicti[k], dict):
            dicti[k] = pop_nested_nulls(dicti[k])
        elif not dicti[k]:
            dicti.pop(k)
    return dicti

Output for pop_nested_nulls(dicti)

{'k0_l0': {'k0_l1': {'k0_l2': {'k1_1': 1,
                               'k2_2': 2.2}},
           'k2_l1': 'not '
                    'none'},
 'k1_l0': 'l0'}

answered Jan 19 at 13:54

Echo9k's user avatar

Echo9kEcho9k

4865 silver badges9 bronze badges

If the values in the dictionary were unique too, then I used this solution:

keyToBeDeleted = None
for k, v in mydict.items():
    if(v == match):
        keyToBeDeleted = k
        break
mydict.pop(keyToBeDeleted, None)

Peter Mortensen's user avatar

answered Nov 23, 2022 at 13:39

Ganesh S's user avatar

Ganesh SGanesh S

3736 silver badges25 bronze badges

Проблема связана с тем, что вы пытаетесь модифицировать словарь, по элементам которого итерируетесь.
В условиях вашего кода это не проблема. Но вы должны сначала прежде чем начнётся цикл с удалениями) взять список пар элементов из вашего словаря.
products.items() возвращает не список, а итератор по элементам словаря. Само собой этот итератор ломается как только вы удаляете из словаря первый элемент.
Но если этот итератор до первого удаления полностью превратить в список, то удалять потом можно что хотите.

for product_id, value in list(products.items()):
    if value['g_1'] == 0:
        del products[product_id]

Или так:

new_products_dict = {k: v for k, v in products.items() if v['g_1'] != 0}

Здесь создаётся новый словарь из элементов, которые удовлетворяют вашим условиям.

products = {
    '00000234': {'value1': 0, 'value2': 23},
    '567333': {'value1': 5, 'value2': 23},
    '23234243': {'value1': 25, 'value2': 23},
}
products = {product_id: values for product_id, values in products.items() if values['value1']}
print(products)
# {'567333': {'value1': 5, 'value2': 23}, '23234243': {'value1': 25, 'value2': 23}}

Или

spoiler

Создай еще один словарь, проверяй условие в цикле
если проходит по твоим параметрам (что нет параметров равных 0) добавляй в новый словарь,
по окончании цикла возвращай новый словарь

I want pop out all the large values and its keys in a dictionary, and keep the smallest. Here is the part of my program

for key,value in dictionary.items():
    for key1, value1 in dictionary.items(): 
            if key1!= key and value > value1:
                dictionary.pop(key)             
    print (dictionary)  

Which results in

RuntimeError: dictionary changed size during iteration    

How can I avoid this error?

martineau's user avatar

martineau

119k25 gold badges164 silver badges294 bronze badges

asked Nov 22, 2012 at 20:34

YXH's user avatar

8

In Python3, Try

for key in list(dict.keys()):
    if condition:
        matched
        del dict[key]

1 more thing should be careful when looping a dict to update its key:

Code1:

keyPrefix = ‘keyA’
for key, value in Dict.items():
    newkey = ‘/’.join([keyPrefix, key])
    Dict[newkey] = Dict.pop(key)

Code2:

keyPrefix = ‘keyA’
for key, value in Dict.keys():
    newkey = ‘/’.join([keyPrefix, key])
    Dict[newkey] = Dict.pop(key)

Result of code1/code2 is:

{‘keyA/keyA/keyB’ : ”, ‘keyA/keyA/keyA’: ”}

My way to resolve this unexpected result:

    Dict = {‘/’.join([keyPrefix, key]): value for key, value in Dict.items()}

Link: https://blog.gainskills.top/2016/07/21/loop-a-dict-to-update-key/

answered Sep 23, 2015 at 6:38

Xb74Dkjb's user avatar

Xb74DkjbXb74Dkjb

9849 silver badges20 bronze badges

0

Alternative solutions

If you’re looking for the smallest value in the dictionary you can do this:

min(dictionary.values())

If you cannot use min, you can use sorted:

sorted(dictionary.values())[0]

Why do I get this error?

On a side note, the reason you’re experiencing an Runtime Error is that in the inner loop you modify the iterator your outer loop is based upon. When you pop an entry that is yet to be reached by the outer loop and the outer iterator reaches it, it tries to access a removed element, thus causing the error.
If you try to execute your code on Python 2.7 (instead of 3.x) you’ll get, in fact, a Key Error.

What can I do to avoid the error?

If you want to modify an iterable inside a loop based on its iterator you should use a deep copy of it.

answered Nov 22, 2012 at 20:55

Nadir Sampaoli's user avatar

Nadir SampaoliNadir Sampaoli

5,3654 gold badges22 silver badges32 bronze badges

6

You can use copy.deepcopy to make a copy of the original dict, loop over the copy while change the original one.

from copy import deepcopy

d=dict()
for i in range(5):
    d[i]=str(i)

k=deepcopy(d)

d[2]="22"
print(k[2])
#The result will be 2.

Your problem is iterate over something that you are changing.

answered Nov 22, 2012 at 21:02

Arthur Julião's user avatar

Arthur JuliãoArthur Julião

8391 gold badge14 silver badges29 bronze badges

1

Record the key during the loop and then do dictionary.pop(key) when loop is done. Like this:

for key,value in dictionary.items():
    for key1, value1 in dictionary.items(): 
            if key1!= key and value > value1:
                storedvalue = key
    dictionary.pop(key)  

David Heffernan's user avatar

answered Nov 22, 2012 at 20:37

Odif Yltsaeb's user avatar

Odif YltsaebOdif Yltsaeb

5,52312 gold badges47 silver badges80 bronze badges

2

Here is one way to solve it:

  1. From the dictionary, get a list of keys, sorted by value
  2. Since the first key in this list has the smallest value, you can do what you want with it.

Here is a sample:

# A list of grades, not in any order
grades = dict(John=95,Amanda=89,Jake=91,Betty=97)

# students is a list of students, sorted from lowest to highest grade
students = sorted(grades, key=lambda k: grades[k])

print 'Grades from lowest to highest:'
for student in students:
    print '{0} {1}'.format(grades[student], student)

lowest_student = students[0]
highest_student = students[-1]
print 'Lowest grade of {0} belongs to {1}'.format(grades[lowest_student], lowest_student)
print 'Highest grade of {0} belongs to {1}'.format(grades[highest_student], highest_student)

The secret sauce here is in the sorted() function: instead of sorting by keys, we sorted by values.

answered Nov 22, 2012 at 20:57

Hai Vu's user avatar

Hai VuHai Vu

37k11 gold badges66 silver badges92 bronze badges

If you want to just keep the key with the smallest value, I would do it by first finding that item and then creating a new dictionary containing only it. If your dictionary was d, something like this would do that in one line:

d = dict((min(d.items(), key=lambda item: item[1]),))

This will not only avoid any issues about updating the dictionary while iterating it, it is probably faster than removing all the other elements.

If you must do the modifications in-place for some reason, the following would work because it makes a copy of all the keys before modifying the dictionary:

key_to_keep = min(d.items(), key=lambda item: item[1])[0]

for key in list(d):
    if key != key_to_keep:
        d.pop(key)

answered Nov 22, 2012 at 21:09

martineau's user avatar

martineaumartineau

119k25 gold badges164 silver badges294 bronze badges

As I read your loop right now, you’re looking to keep only the single smallest element, but without using min. So do the opposite of what your code does now, check if value1 < minValueSoFar, if so, keep key1 as minKeySoFar. Then at the end of the loop (as Zayatzz suggested), do a dictionary.pop(minKeySoFar)

As an aside, I note that the key1!=key test is irrelevant and computationally inefficient assuming a reasonably long list.

minValueSoFar = 9999999;   # or whatever
for key,value in dictionary.items():
    if value < minValueSoFar:
        minValueSoFar = value
        minKeySoFar = key
dictionary.pop(minKeySoFar)   # or whatever else you want to do with the result

answered Nov 22, 2012 at 20:48

mackworth's user avatar

mackworthmackworth

5,8532 gold badges29 silver badges49 bronze badges

An alternative solution to dictionary changed size during iteration:

for key,value in list(dictionary.items()):
    for key1, value1 in list(dictionary.items()): 
            if key1!= key and value > value1:
                dictionary.pop(key)             
print (dictionary)  

Better use it with caution! when using this type of code, because list(dictionary.items()) calculated when the complier enters first time to loop. Therefore any change made on dictionary won’t affect process inside the current loop.

answered Dec 5, 2019 at 6:44

furkanayd's user avatar

furkanaydfurkanayd

8017 silver badges19 bronze badges

You could create a list with the vaules you want to delete and than run a second for loop:

for entry in (listofkeystopop):
        dictionary.pop(entry)

answered Jan 13, 2021 at 22:09

r0tt's user avatar

r0ttr0tt

3793 silver badges20 bronze badges

  1. Creating a Shallow Copy of the Dictionary
  2. Casting Dictionary Items to a List
  3. Appending Keys to an Empty List

Fix Error - Dictionary Changed Size During Iteration

This Runtime error occurs when we remove, modify, or add new entries in a dictionary object during iteration. This error occurs when iterating through a dictionary but virtually all iterable objects regardless of the programming language used.

The code snippet below illustrates how this error comes about when iterating through a dictionary and making changes simultaneously.

cars = {
 "brand": "Tesla",
 "model": "Model S Plaid",
 "year":  2021
 }

for x in cars.keys():
  cars["color"] = "white"
print(x)

In the code block above, we add a new item to the original dictionary while iterating. This will return a Runtime Error, letting us know that the dictionary size changed during iteration, implying that we cannot modify the dictionary while iterating simultaneously.

Sample Code:

Traceback (most recent call last):
File "<string>", line 8, in <module>
RuntimeError: dictionary changed size during iteration

While performing any iteration to an object, both deletion, addition, or modification are considered an alteration and cannot be performed while iterating. The code example below demonstrates that this error will also persist if we modify the dictionary while iterating. Therefore, we will still get the same error if we remove an existing item from a dictionary while iterating.

Sample Code:

cars = {
 "brand": "Tesla",
 "model": "Model S Plaid",
 "year":  2021
 }

for x in cars.keys():
    del cars["model"]
print(cars)

Output:

Traceback (most recent call last):
File "<string>", line 8, in <module>
RuntimeError: dictionary changed size during iteration

In Python 3, iterating over a changing object is considered a bad style of writing code and unsafe. Generally, in Programming, we cannot mutate an object while iterating over it simultaneously; this rule extends to iterables such as lists and even arrays.

However, if a function mutates an object, we must make sure that the function only mutates a copy of the original object, leaving the original object intact. This is one of the widely used approaches of making alterations to objects while iterating through them simultaneously.

This is a good practice and the best way of avoiding instances of creating an infinite loop that may eventually lead to memory exhaustion. Several solutions can be used to handle this error, and we will discuss each one here.

Creating a Shallow Copy of the Dictionary

Python provides us with the copy() module that allows us to create a copy of an object with no binding to the original object. This lets us freely modify the copy of the object, leaving the original object intact.

Note that the same cannot be realized by using the assignment operator in Python. Using the assignment operator does not create a copy of the original object but rather a variable that refers to the original object.

Therefore any modifications made to the new object will also affect the original object. New developers often misuse this operator.

Sample Code:

import copy
cars = {
 "brand": "Tesla",
 "model": "Model S Plaid",
 "year":  2021,
 }

#creating a shallow copy
cars_copy = copy.copy(cars)

for x in cars_copy.keys():
    cars["color"] = "black"
    
print(cars)
print(cars_copy)

Output:

{'brand': 'Tesla', 'model': 'Model S Plaid', 'year': 2021, 'color': 'black'}
{'brand': 'Tesla', 'model': 'Model S Plaid', 'year': 2021}

In the sample code provided, we have used the copy module’s copy function to create a dictionary copy that we can freely iterate without affecting the original dictionary. Making changes to a dictionary copy allows us to iterate over the dictionary without encountering an error.

Alternatively, we can use the ** operator that is often referred to as the two asterisk operators to rewrite the code above, as shown below.

Sample Code:

cars = {
 "brand": "Tesla",
 "model": "Model S Plaid",
 "year":  2021
 }

#creating a shallow copy
cars_copy = {**cars}


for x in cars_copy.keys():
  cars["color"] = "black"
  
print(cars)

The ** operator can take key-value pairs from one dictionary and dump them into another dictionary.

Although the operator is widely used to pass in keyword arguments in Python, we have used the operator to unpack the dictionary and obtain the key-value pairs in the code above. We then create a copy of the dictionary and dump the unpacked values in this new dictionary.

Output:

'brand': 'Tesla', 'model': 'Model S Plaid', 'year': 2021, 'color': 'black'}

Deleting a key-value pair from a dictionary is no exception either when performing an iteration and thus should follow a similar approach. Therefore using the same procedure, we will delete the key named model and its value Model S Plaid as shown below.

Sample Code:

import copy
cars = {
 "brand": "Tesla",
 "model": "Model S Plaid",
 "year":  2021,
 "color": "black"
 }
 
cars_copy = copy.copy(cars)
 
for x in cars_copy.keys():
    if x == "model":
        del cars["model"]
   
print(cars)

Output:

{'brand': 'Tesla', 'year': 2021, 'color': 'black'}

Another solution would be to create a copy of the keys that we can then iterate over while modifying the dictionary. However, this can only work in Python 2 and not Python 3 because when done in Python 3, the keys do not return the iterable.

Sample Code:

cars = {
 "brand": "Tesla",
 "model": "Model S Plaid",
 "year":  2021,
 "color": "black"
 }

key_copys = list(cars.keys())
print(key_copys)

for key in list(key_copys):
    if cars[key] == "model":
        cars.pop("model")
        
print(cars)

Sample Output:

['brand', 'model', 'year', 'color']
{'brand': 'Tesla', 'model': 'Model S Plaid', 'year': 2021, 'color': 'black'}

Casting Dictionary Items to a List

Since we cannot iterate over the dictionary while making changes, we can instead create a casting list and iterate over the list while making changes to the dictionary. Iterating over the casting list instead of the original dictionary does not return a Runtime error.

Sample Code:

cars = {
 "brand": "Tesla",
 "model": "Model S Plaid",
 "year":  2021
 }

for i in list(cars):
    cars["color"] = "black"
    
print(cars)

Output:

{'brand': 'Tesla', 'model': 'Model S Plaid', 'year': 2021, 'color': 'black'}

Appending Keys to an Empty List

To avoid changing the dictionary while iterating, we can create an empty list containing the dictionary keys while we perform the iteration. Using this empty list, we can append all the keys that we want to remove or change and then use the pop() function to remove the keys or the append function to add new key-value pairs.

This can be executed as shown in the code below.

Sample Code:

cars = {
 "brand": "Tesla",
 "model": "Model S Plaid",
 "year":  2021
 }

list = []

for i in cars:
    list.append(i)
    
for x in list:
    if x == "model":
        cars.pop(x)
    
print(cars)

Output:

{'brand': 'Tesla', 'year': 2021}

As shown below, we can add a new key-value pair to the dictionary using the same procedure while iterating using the for loop.

Sample Code:

cars = {
 "brand": "Tesla",
 "model": "Model S Plaid",
 "year":  2021
 }
 
list = []

for i in cars:
    list.append(i)
    
for x in list:
    cars["color"] = "black"
  
print(cars)

Output:

{'brand': 'Tesla', 'model': 'Model S Plaid', 'year': 2021, 'color': 'black'}

The Runtimeerror: dictionary changed size during iteration occurs if we tend to change the size of the dictionary while iterating over it. This type of error is an exception error that pops up when the generated error does not fall into any other categories. This error can be resolved by the handlers who are handling exception clauses.

What is RuntimeError?

The RuntimeError is detected when the raised error does not belong to any other error categories. In this type of error, the values are associated with the strings, which shows the exact cause of the error. This error belongs to the exception error category.

In such errors, even though there are some mistakes in the syntax, it gets a pass until its execution. In this case, the interpreter will find the error and stop it with a message describing the exception.

Causes Of RuntimeError

  • This type of error arises if there are some variables and function names that are misspelled or capitalized incorrectly but placed in the correct sequence then the syntax error will not arise, but as soon as you run the program, an error message will pop up, and the program would not be executed.
  • Another instance where this type of error would cause is when you try to perform operations on the wrong data type.
  • This type of error can also arise when the values which can not be converted into any integer get used with the “int” function.

The runtimeerror: dictionary changed size during iteration is the error that arises in python when we change the size of the dictionary, frequently used data structure during iteration.

If you are someone new and perhaps not acquainted with the terms, then here is a little help for you. Basically, Iteration is a term that is used when the sequences of instructions and codes are put until it gives an iterator as a result. Sometimes people confuse the term iterator with the term iterable due to its common nature. But these two terms have two completely different meanings. The Iterable is an object which uses the “__iter__” command to return an Iterator.

The runtimeerror: dictionary changed size during iteration is a self-explanatory error message which will arise when you try to add any entries during iteration. While you are looping in the iteration, you are not allowed do any kind of changes in the dictionary; hence when you try to do so, it generates the runtimeerror: dictionary changed size during iteration message.

E.g.

If someone wants to delete a value from the dictionary, the runtimeerror: dictionary changed size during iteration error will be caused.

my_dict = { 'x' : 1, 'y' : 2, 'z' : 3, 'a' : 4}

for i in my_dict:
    del my_dict["a"]
print (my_dict)     

Output:

Runtimeerror: dictionary changed size during iteration

Solution For Runtimeerror: Dictionary Changed Size During Iteration

If you face any runtimeerror: dictionary changed size during iteration error, you can use one of the methods mentioned below.

Making a shallow copy

By making a shallow copy, you can store the references of the original elements in the dictionary. it basically does not create or recurse the nested objects but stores their references. It is not the most convenient method, but it can surely create a solution for the runtimeerror: dictionary changed size during iteration error.

E.g.:

my_dict = { ' x ' : 1, ' y ' : 2, ' z ' : 3, ' a' : 4}

my_dict_copy = my_dict.copy()
for i in my_dict:
        del my_dict_copy[i]

print (my_dict)     
print(my_dict_copy)

Making a copy of Dictionary Keys

Instead of making a copy of the entire dictionary which can be a bit of a mess, you can create a copy of the dictionary keys and use them as iterators. This can give you a proper solution to the error message without taking up extra space as it will create only a copy of the required keys.

E.g.:

my_dict = { ' x ' : 1, ' y ' : 2, ' z ' : 3, ' a' : 4}

key_copy = tuple(my_dict.keys())
for a in key_copy:
           del my_dict[a] 

Using Deferred Update

If you want to take other ways than just creating copies of the present dictionary, you can opt for the deferred update method. This method prohibits any changes made during the programming from being applied to the database till the iteration is over. It is the most effective way to avoid the runtimeerror: dictionary changed size during iteration error message.

E.g.:

my_dict = { ' x ' : 1, ' y ' : 2, ' z ' : 3, ' a' : 4}

keys_to_be_removed = []
for i in my_dict:
    keys_to_be_removed.append(i)

for a in keys_to_be_removed:
    del my_dict[a]
  

FAQ

How to differentiate RuntimeError from SyntaxError?

A runtimeError is basically the error caused due to misspelling or misplacement in the syntax, which gets a pass for syntaxError but does not run. But on the other hand, the syntaxError is generally related to the placement and use of commands which get caught by the interpreter or compiler.

How do I get the size of a dictionary in Python?

To find the size of the dictionary, you can use the len() function. This function will return the size of the dictionary in terms of the number of key-value pairs present in the dictionary.

E.g.

my_dict = { ' x ' : 1, ' y ' : 2, ' z ' : 3, ' a' : 4}
print("The length of the dictionary is {}".format(len(my_dict)))

How do you check if a key exists in a dictionary in python?

You can check the existence of a key in a python dictionary using the has_key() method. If the key is available, it will return the output as a true or otherwise a false.

E.g.

def checkKey(dic, key):
     
    if dic.has_key(key):
        print("Present, value =", dic[key])
    else:
        print("Not present")
 
# Driver Function
my_dict = {'x': 1, 'b':2, 'z':3}
key = 'b'
checkKey(dic, key)
 
key = 'w'
checkKey(dic, key)

Conclusion

This article will help you find the cause for the RuntimeError: dictionary changed size during the iteration and will help you with its solution.

References

Dictionary

Learn more about error handling at PythonClear

Понравилась статья? Поделить с друзьями:
  • Как найти местоположение смартфона если потерял
  • Как найти пользователя по sid в ad
  • Как найти человека загрузив фото в интернет
  • Утечка электроэнергии в квартире как найти
  • Как вы нашли свой цвет волос