Last updated: Apr 8, 2024
Reading timeยท5 min
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()
.
Here is an example of how the error occurs.
my_dict = {'a': 1, 'b': 2, 'c': 3} # โ๏ธ RuntimeError: dictionary changed size during iteration for key in my_dict: print(key) if key == 'b': del my_dict[key]
It is not allowed to change the size of a dictionary while iterating over it.
Changing the size of a dictionary (e.g. removing items from it or adding items to it) while iterating over it is confusing for the Python interpreter.
One way to solve the error is to use the dict.copy
method to create a shallow
copy of the dictionary and iterate over the 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}
The dict.copy() method returns a shallow copy of the object on which the method was called.
We are not allowed to iterate over the dictionary and change its size, however, iterating over a copy of the dictionary and changing the size of the original dictionary is permitted.
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}
The dict.keys() method returns a new view of the dictionary's keys.
my_dict = {'id': 1, 'name': 'Bobby Hadz'} print(my_dict.keys()) # ๐๏ธ dict_keys(['id', 'name'])
We used the list()
class to create a copy of the keys in the example.
The list class takes an iterable and returns a list object.
You can also use the dict.items()
method in a similar way.
However, notice that when using dict.items()
, we have access to the key and
value of the current iteration.
my_dict = {'a': 1, 'b': 2, 'c': 3} for key, value in list(my_dict.items()): print(key, value) # ๐๏ธ a 1, b 2, c 3 if key == 'b': del my_dict[key] print(my_dict) # ๐๏ธ {'a': 1, 'c': 3}
We used the list()
class to create a copy of the dictionary's items.
The dict.items() method returns a new view of the dictionary's items ((key, value) pairs).
my_dict = {'id': 1, 'name': 'Alice'} print(my_dict.items()) # ๐๏ธ dict_items([('id', 1), ('name', 'Alice')])
You can also use a dict comprehension to solve the error.
my_dict = {'a': 1, 'b': 2, 'c': 3} keys_to_remove = ['a', 'b'] my_dict = {key: value for key, value in my_dict.items() if key not in keys_to_remove} print(my_dict) # ๐๏ธ {'c': 3}
We stored the keys we wanted to remove in a keys_to_remove
list and used a
dict comprehension to iterate over the key-value pairs of the dictionary.
Dict comprehensions are very similar to list comprehensions.
On each iteration, we check if the current key is not present in the
keys_to_remove
list.
If the condition is met, the current key-value pair is returned.
All of the keys from the keys_to_remove
list get removed from the dictionary.
for
loops to solve the errorYou can also use two separate for loops to solve the error.
my_dict = {'a': 0, 'b': 1, 'c': 0} keys_to_remove = [] for key, value in my_dict.items(): if not value: keys_to_remove.append(key) print(keys_to_remove) # ๐๏ธ ['a', 'c'] for key in keys_to_remove: del my_dict[key] print(my_dict) # ๐๏ธ {'b': 1}
The first for
loop iterates over the dictionary and adds the keys that should
be removed to a list.
The second for
loop iterates over the list of keys and uses the del
statement to remove them.
We never actually change the dictionary's size while iterating over it, so the error isn't raised.
Which approach you pick is a matter of personal preference. I'd go with using the dict.copy() method.
The method returns a shallow copy of the dictionary, so it's quite easy to read and solves the issue of not being able to iterate over a dictionary and change its size.
The Python "RuntimeError: Set changed size during iteration in Python" occurs
when we change the size of a set
object when iterating over it.
To solve the error, use the copy()
method to create a shallow copy of the
set
that you can iterate over, e.g. my_set.copy()
.
Here is an example of how the error occurs.
my_set = {'Alice', 'Bob', 'Carl'} for i in my_set: print(i) if i == 'Bob': # โ๏ธ RuntimeError: Set changed size during iteration my_set.remove(i)
It is not allowed to change the size of a set
while iterating over it.
set.copy()
method to solve the errorOne way to solve the error is to use the set.copy()
method to create a shallow
copy of the set
object and iterate over the copy.
my_set = {'Alice', 'Bob', 'Carl'} for i in my_set.copy(): print(i) if i == 'Bob': my_set.remove(i) print(my_set) # ๐๏ธ {'Alice', 'Carl'}
set
and changing its size messes up with the iterator, so creating a shallow copy and iterating over the copy solves the issue.set
objectWe could have also used a list comprehension to filter out elements from the set.
my_set = {'Alice', 'Bob', 'Carl'} my_new_set = set([i for i in my_set if i != 'Bob']) print(my_new_set) # ๐๏ธ {'Carl', 'Alice'}
Make sure to pass the list to the
set() class to convert
the result to a set
object.
Here is another example of using a list comprehension to filter out elements
from a set
.
my_set = {1, 2, 3, 4, 5, 6} my_new_set = set([i for i in my_set if i % 2 == 0]) print(my_new_set) # ๐๏ธ {2, 4, 6}
The final set
contains only elements that are divisible by 2
.
Set objects are an unordered collection of unique elements.
for
loops to solve the errorYou can also use 2 for
loops to solve the error.
my_set = {'Alice', 'Bob', 'Carl', 'Bobby'} elements_to_remove = [] for element in my_set: if 'Bob' in element: elements_to_remove.append(element) print(elements_to_remove) # ๐๏ธ ['Bob', 'Bobby'] for element in elements_to_remove: my_set.remove(element) print(my_set) # ๐๏ธ {'Carl', 'Alice'}
The first for
loop iterates over the set
and adds the elements that should
be removed to a new list.
The second for
loop iterates over the list and removes each element from the
set
.
We never remove items from the set
while iterating over it, so the error isn't
raised.
You can learn more about the related topics by checking out the following tutorials: