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


Practica Python con PyQuizzes

En la sección de PyQuizzes puedes encontrar ejercicios prácticos explicados pormenorizado para mejorar tus habilidades como pythonista. ¡No te los pierdas!


Tutorial Python online

Aprender Python de forma gratuita siguiendo las secciones del tutorial de Python.


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.

Disponible en:

Compartir

Deja una respuesta

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

Ver más

  • Responsable: Oscar Ramirez.
  • Finalidad:  Moderar los comentarios.
  • Legitimación:  Por consentimiento del interesado.
  • Destinatarios y encargados de tratamiento: No se ceden o comunican datos a terceros para prestar este servicio. El Titular ha contratado los servicios de alojamiento web a ionos (1&1) que actúa como encargado de tratamiento.
  • Derechos: Acceder, rectificar y suprimir los datos.
  • Información Adicional: Puede consultar la información detallada en la Política de Privacidad.

Publicar un comentario