Python Quiz 6 – Iterar correctamente en diccionarios en Python

Pyquiz 6 - iterando correctamente en diccionarios

Pregunta principal del pyquiz:

>>> dd = dict(color='Red', brand='Too')
>>> lst = []
>>> keys = list(dd.keys())
>>> for d in keys:
...     lst.append(d)
...     del dd[d]
...
>>> print(lst)
- ?? -
# A - ['color', 'brand']
# B - RuntimeError
# C - ['Red', 'Too']

Concepto y explicación

La idea principal de esta pregunta es hace énfasis en el correcto uso y manipulación de las claves de los diccionarios cuando se iteran sus valores.

Como se vió en el PyQuiz 3 si se cambian si se está iterando en un diccionario y se intenta eliminar los valores del mismo, se eleva una excepción RuntimeError, pero en este caso no es así.

La lógica general de este pyquiz es:

  • Inicializa un diccionario.
  • Crea una lista vacía para guardar las claves del diccionario.
  • Guarda en una lista auxiliar las claves del diccionario.
  • Va iterando en todas las claves de la lista auxiliar y borrando elementos del diccionario.
  • Imprime el contenido de lst.

Veamos en profundidad qué ocurre en esta ejecución:

>>> dd = dict(color='Red', brand='Too')
>>> dd
{'color': 'Red', 'brand': 'Too'}
>>> lst = []
>>> lst
[]
>>> keys = list(dd.keys())
>>> keys
['color', 'brand']

A continuación se pueden ver las 2 iteraciones que se realizan:

# lst = [], d = 'color', dd = dict(color='Red', brand='Too')
>>> for d in keys:
...     lst.append(d)
...     del dd[d]
...
# lst = ['color'], d = 'brand', dd = dict(brand='Too')
>>> for d in keys:
...     lst.append(d)
...     del dd[d]
...
# lst = ['color', 'brand'], d = 'brand', dd = dict()
>>> print(lst)
['color', 'brand']

Efectivamente, la respuesta correcta es ['color', 'brand'], pero como se puede ver en la ejecución, el diccionario dd va perdiendo elementos a medida que la lista lst va aumentando elementos.

Este ejemplo es de vital importancia si se analiza el comportamiento de las claves de un diccionario en Python 3:

>>> dd = dict(color='Red', brand='Too')
>>> d_keys = dd.keys()
>>> d_values = dd.values()
>>> type(d_keys)
<class 'dict_keys'>
>>> type(d_values)
<class 'dict_values'>
>>> d_keys, d_values
(dict_keys(['color', 'brand']), dict_values(['Red', 'Too']))
>>> dd['num'] = 89
>>> d_keys, d_values
(dict_keys(['color', 'brand', 'num']), dict_values(['Red', 'Too', 89]))
>>> dd['name'] = 'Juan'
>>> d_keys, d_values
(dict_keys(['color', 'brand', 'num', 'name']), dict_values(['Red', 'Too', 89, 'Juan']))
>>> del dd['name']
>>> d_keys, d_values
(dict_keys(['color', 'brand', 'num']), dict_values(['Red', 'Too', 89]))

Como se puede ver en los ejemplos, las variables de values y de keys de un diccionario en Python, están ligadas a sus valores en el diccionario, por lo que cambian dinámicamente a medida que lo hace el diccionario.

Aunque este comportamiento particular se produzca en Python 3, no se puede confundir con que son listas diferentes, y por lo tanto eliminar contenido de las mismas eleva excepciones como se ve a continuación:

>>> d_keys = dd.keys()
>>> dd
{'color': 'Red', 'brand': 'Too'}
>>> d_keys
dict_keys(['color', 'brand'])
>>> del d_keys[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'dict_keys' object doesn't support item deletion

En Python 2 la situación era diferente dado que el método dict.keys() devolvía una lista en vez de un dict_keys o un dict_values, por lo que es recomendable conocer bien los conceptos detrás de los valores y las claves de los diccionarios en Python.

Solución

Por tanto la solución correcta es la A:

A) [‘color’, ‘brand’]




Libros recomendados para aprender Python

Estos son los libros que pueden ayudarte a aprender Python, aprender a programar, tipos de datos, algoritmia y mucho más.

Libro Python a fondo Disponible en:

Compartir

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Publicar un comentario