Corregir Python error = Dictionary Changed Size During Iteration
- Creación de una copia superficial del diccionario
- Transmitir elementos del diccionario a una lista
- Agregar claves a una lista vacía
Este error de tiempo de ejecución ocurre cuando eliminamos, modificamos o agregamos nuevas entradas en un objeto de diccionario durante la iteración. Este error se produce cuando se itera a través de un diccionario pero prácticamente todos los objetos iterables independientemente del lenguaje de programación utilizado.
El siguiente fragmento de código ilustra cómo se produce este error al recorrer un diccionario y realizar cambios simultáneamente.
cars = {"brand": "Tesla", "model": "Model S Plaid", "year": 2021}
for x in cars.keys():
cars["color"] = "white"
print(x)
En el bloque de código anterior, agregamos un nuevo elemento al diccionario original mientras iteramos. Esto devolverá un error de tiempo de ejecución, que nos informa que el tamaño del diccionario cambió durante la iteración, lo que implica que no podemos modificar el diccionario mientras se itera simultáneamente.
Código de muestra:
Traceback (most recent call last):
File "<string>", line 8, in <module>
RuntimeError: dictionary changed size during iteration
Al realizar cualquier iteración en un objeto, tanto la eliminación como la adición o la modificación se consideran una alteración y no se pueden realizar durante la iteración. El siguiente ejemplo de código demuestra que este error también persistirá si modificamos el diccionario mientras iteramos. Por lo tanto, seguiremos obteniendo el mismo error si eliminamos un elemento existente de un diccionario mientras iteramos.
Código de muestra:
cars = {"brand": "Tesla", "model": "Model S Plaid", "year": 2021}
for x in cars.keys():
del cars["model"]
print(cars)
Producción :
Traceback (most recent call last):
File "<string>", line 8, in <module>
RuntimeError: dictionary changed size during iteration
En Python 3, iterar sobre un objeto cambiante se considera un mal estilo de escritura de código e inseguro. Generalmente, en Programación, no podemos mutar un objeto mientras iteramos sobre él simultáneamente; esta regla se extiende a iterables como listas e incluso matrices.
Sin embargo, si una función muta un objeto, debemos asegurarnos de que la función solo muta una copia del objeto original, dejando el objeto original intacto. Este es uno de los enfoques más utilizados para realizar alteraciones en objetos mientras se itera a través de ellos simultáneamente.
Esta es una buena práctica y la mejor manera de evitar casos de creación de un bucle infinito que eventualmente puede llevar al agotamiento de la memoria. Se pueden usar varias soluciones para manejar este error, y discutiremos cada una aquí.
Creación de una copia superficial del diccionario
Python nos proporciona el módulo copy()
que nos permite crear una copia de un objeto sin vinculación al objeto original. Esto nos permite modificar libremente la copia del objeto, dejando intacto el objeto original.
Tenga en cuenta que no se puede realizar lo mismo utilizando el operador de asignación en Python. El uso del operador de asignación no crea una copia del objeto original, sino más bien una variable que se refiere al objeto original.
Por lo tanto, cualquier modificación realizada en el nuevo objeto también afectará al objeto original. Los nuevos desarrolladores a menudo hacen un mal uso de este operador.
Código de muestra:
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)
Producción :
{'brand': 'Tesla', 'model': 'Model S Plaid', 'year': 2021, 'color': 'black'}
{'brand': 'Tesla', 'model': 'Model S Plaid', 'year': 2021}
En el código de muestra proporcionado, hemos utilizado la función copy
del módulo de copia para crear una copia de diccionario que podemos iterar libremente sin afectar el diccionario original. Hacer cambios en una copia de diccionario nos permite iterar sobre el diccionario sin encontrar un error.
Alternativamente, podemos usar el operador **
que a menudo se conoce como los dos operadores de asterisco para reescribir el código anterior, como se muestra a continuación.
Código de muestra:
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)
El operador **
puede tomar pares clave-valor de un diccionario y volcarlos en otro diccionario.
Aunque el operador se usa ampliamente para pasar argumentos de palabras clave en Python, hemos usado el operador para descomprimir el diccionario y obtener los pares clave-valor en el código anterior. Luego creamos una copia del diccionario y volcamos los valores descomprimidos en este nuevo diccionario.
Producción :
'brand': 'Tesla', 'model': 'Model S Plaid', 'year': 2021, 'color': 'black'}
Eliminar un par clave-valor de un diccionario tampoco es una excepción al realizar una iteración y, por lo tanto, debe seguir un enfoque similar. Por lo tanto, utilizando el mismo procedimiento, eliminaremos la clave denominada model
y su valor Model S Plaid
como se muestra a continuación.
Código de muestra:
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)
Producción :
{'brand': 'Tesla', 'year': 2021, 'color': 'black'}
Otra solución sería crear una copia de las claves sobre la que luego podamos iterar mientras modificamos el diccionario. Sin embargo, esto solo puede funcionar en Python 2 y no en Python 3 porque cuando se hace en Python 3, las claves no devuelven el iterable.
Código de muestra:
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)
Salida de muestra:
['brand', 'model', 'year', 'color']
{'brand': 'Tesla', 'model': 'Model S Plaid', 'year': 2021, 'color': 'black'}
Transmitir elementos del diccionario a una lista
Dado que no podemos iterar sobre el diccionario mientras hacemos cambios, podemos crear una lista de conversión e iterar sobre la lista mientras hacemos cambios en el diccionario. La iteración sobre la lista de conversión en lugar del diccionario original no devuelve un error de tiempo de ejecución.
Código de muestra:
cars = {"brand": "Tesla", "model": "Model S Plaid", "year": 2021}
for i in list(cars):
cars["color"] = "black"
print(cars)
Producción :
{'brand': 'Tesla', 'model': 'Model S Plaid', 'year': 2021, 'color': 'black'}
Agregar claves a una lista vacía
Para evitar cambiar el diccionario mientras iteramos, podemos crear una lista vacía que contenga las claves del diccionario mientras realizamos la iteración. Usando esta lista vacía, podemos agregar todas las claves que queremos eliminar o cambiar y luego usar la función pop()
para eliminar las claves o la función add
para agregar nuevos pares clave-valor.
Esto se puede ejecutar como se muestra en el código siguiente.
Código de muestra:
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)
Producción :
{'brand': 'Tesla', 'year': 2021}
Como se muestra a continuación, podemos agregar un nuevo par clave-valor al diccionario usando el mismo procedimiento mientras iteramos usando el bucle for.
Código de muestra:
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)
Producción :
{'brand': 'Tesla', 'model': 'Model S Plaid', 'year': 2021, 'color': 'black'}
Isaac Tony is a professional software developer and technical writer fascinated by Tech and productivity. He helps large technical organizations communicate their message clearly through writing.
LinkedInArtículo relacionado - Python Dictionary
- Cómo comprobar si existe una clave en un diccionario en Python
- Convertir un diccionario en una lista en Python
- Cómo obtener todos los archivos de un directorio
- Cómo encontrar el valor máximo en el Diccionario Python
- Cómo ordenar un diccionario Python por valor
- Cómo fusionar dos diccionarios en Python 2 y 3