Artículos de Tecnología > Data Science

Python: trabajando con diccionarios

Yan Orestes
Yan Orestes

Estoy programando un sistema de agenda telefónica en Python . Para eso, necesito almacenar los números de los contactos. Al principio, podemos pensar en usar una lista:

telefones = ['1234-5678', '9999-9999', '8765-4321', '8877-7788']

Bien, tenemos los números de teléfono almacenados. Pero ... ¿cuál es el punto de tener una lista de números sueltos? ¿De quién es el número en la segunda posición?

Necesitamos conectar de alguna manera los teléfonos a sus respectivos contactos. Un tipo que puede ayudarnos con eso es la tupla:

contacto = ('Yan', '1234-5678')

Para no necesitar una variable para cada contacto, podemos ponerlos directamente en una lista de contactos:

contactos_lista = [('Yan', '1234-5678'), ('Pedro', '9999-9999'),
                    ('Ana', '8765-4321'), ('Marina', '8877-7788')]

¡Muy bien! Si queremos acceder al número de teléfono de Marina, podemos hacer:

print(contactos_lista[3][1])

Y el resultado:

8877-7788

¡Lo hicimos! Ahora, el número de Pedro: ... Pero espera, ¿cuál es la posición de Pedro en nuestra lista de contactos?

Tenga en cuenta que, tal como están las cosas, apenas importa tener guardados los nombres de los contactos, porque solo podemos acceder a cada contacto por su posición en la lista. ¿No hay mejor manera?

Mapear contactos con un diccionario

Hasta ahora tenemos una lista de contactos donde al menos cada contacto tiene su nombre y teléfono conectados. Sin embargo, por ahora, solo podemos acceder a un contacto individualmente por su posición en la lista, y no por su propio nombre.

Lo ideal sería mapear el nombre de cada contacto con su teléfono, evitando otros problemas.

Por ejemplo, podemos decir que el contacto Yan tiene el número de teléfono 1234-5678. Entonces, cuando queremos saber cuál es el número de teléfono de Yan, simplemente ve a su nombre. De esa manera, no necesitamos memorizar en qué posición de la lista está el teléfono, solo necesitamos saber su nombre de contacto.

Tenga en cuenta que, en este caso, estamos creando una especie de diccionario, similar a los diccionarios de portugués o inglés. En estos diccionarios, tenemos una clave que es la palabra que estamos buscando, que en nuestro caso es el nombre del contacto.

Cuando encontramos esa palabra, podemos ver su significado, es decir, el valor de esa palabra en el idioma, que en nuestro caso es el número de teléfono.

Este tipo de estructura se usa ampliamente en varios lenguajes de programación (pero generalmente tiene otro nombre, como matriz asociativa. Con él, logramos comportarnos de manera similar a los diccionarios.

Bueno, digamos a Python que cree uno de estos diccionarios para nosotros. En Python, usamos llaves ( {}) para construir nuestros diccionarios. En este caso, le decimos a Python que la clave 'Yan'tiene ( :) el valor 1234-5678como su teléfono:

contactos = {'Yan': '1234-5678'}
print(type(contactos))

Y mira el tipo de variable contactosque acabamos de crear:

<class 'dict'>

dict- De hecho, un diccionario. ¿Pero tendremos que volver a escribir todos los datos de contacto que ya hemos incluido en nuestra lista de contactos? También podemos crear un diccionario usando su función de constructor dict()y pasando, como parámetro, una lista de tuplas, como en nuestro caso:

contactos_lista = [('Yan', '1234-5678'), ('Pedro', '9999-9999'),
                    ('Ana', '8765-4321'), ('Marina', '8877-7788')]

contactos = dict(contactos_lista)
print(contactos)

Y ahora:

{'Yan': '1234-5678', 'Pedro': '9999-9999', 'Ana': '8765-4321',
  'Marina': '8877-7788'}

Bien, tenemos nuestra estructura lista! Pero espere un minuto, nuestro diccionario no está en orden alfabético, no tiene orden ... ¿Cómo podemos acceder a sus artículos?

Acceder a elementos en un diccionario

Podemos acceder a sus valores de manera similar a cómo accedemos a los valores de una lista, por ejemplo, con la diferencia de que usamos las teclas que definimos en lugar de los índices numéricos:

print(contatos['Ana'])

Y el resultado:

8765-4321

¡Todo bien! Hasta que, después de un tiempo, quiso ver si podía encontrar el número de teléfono de un viejo amigo Javier. Hice lo siguiente:

print(contatos['Javier'])

Pero mira lo que apareció en la pantalla:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'Javier'

Um ... una excepción de tipo KeyErrorque indica que Javierno se encontró la clave . Pero es un poco extraño imprimir todo este mensaje para el usuario, ¿no? Puede ser confuso ... ¿No podemos reemplazar eso?

Los diccionarios tienen un método específico para buscar valores, get(), en el que podemos pasar como parámetros la clave que queremos y un valor predeterminado para devolver si no se encuentra esa clave:

print(contactos.get('Yan', 'Contacto no encontrado'))
print(contactos.get('Javier', 'Contacto no encontrado'))

Y el resultado:

1234-5678
Contacto no encontrado

¡Mucho mejor ahora!

También podemos verificar si un contacto está en nuestro diccionario usando la palabra clave in:

print('Yan' in contactos)

Y la respuesta:

True

¡Como esperado!

En estos días, encontré un número suelto aquí y quería verificar si estaba en mi calendario:

print('9999-9999' in contactos)

Esta vez, mira el resultado:

False

Huh Pero ese número está en la agenda, ¡es el número de Pedro! ¿Por qué fue el resultado False, entonces?

Resulta que in, usado de esta manera, verifica solo las claves del diccionario, no los valores. Para obtener valores, podemos usar el método values():

print('9999-9999' in contactos.values())

Y la respuesta:

True

¡Ahora si! Tenemos nuestra estructura de mapeo y ya podemos visualizar sus datos. Pero ahora, ¿qué más podemos hacer?

Agregar valores al diccionario

Encontré a mi amigo Javier y finalmente decidí agregar su número a mi directorio telefónico. Pero ... ¿cómo puedo hacer esto con nuestro diccionario de contactos? Traté de usar un método append(), como en las listas, y mira lo que apareció:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'append'

Este método no existe ... Traté de crear otro diccionario y agregarlo, pero el resultado fue este:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'dict' and 'dict'

¡Tampoco funciona! La sintaxis de agregar un elemento a un diccionario es ligeramente diferente a la de otros tipos de Python, pero también bastante objetiva. Por ejemplo, si queremos agregar a Javier a nuestro diccionario de contactos, simplemente asigne su número de teléfono a la tecla 'Javier':

contatos['Javier'] = '8887-7778'
print(contatos)

Ahora mira el diccionario:

{'Yan': '1234-5678', 'Pedro': '9999-9999', 'Ana': '8765-4321',
  'Marina': '8877-7788', 'Javier': '8887-7778'}

¡Funcionó!

Eliminar elementos del diccionario

Desafortunadamente, mi amiga Marina perdió su teléfono celular y, en consecuencia, ya no poseía el número guardado en mi diccionario de contactos. Ahora necesitamos eliminar el elemento que le corresponde. ¿Pero como?

Una manera simple es usar la statement del , así:

del contactos['Marina']
print(contactos)

Y ahora, nuestro diccionario:

{'Yan': '1234-5678', 'Pedro': '9999-9999', 'Ana': '8765-4321',
  'Javier': '8887-7778'}

¡Correcto! Pero, ¿qué pasa si intentamos eliminar un elemento que no existe?

del contactos['Catarina']

Mira lo que pasa:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'Catarina'

¡Um KeyError, como el que obtuvimos al intentar obtener un artículo que no existía! Para evitar esta excepción, también tenemos un método de diccionario que puede ayudarlo - pop().

El método pop(), además de eliminar el elemento con la clave especificada del diccionario, nos devuelve el valor de ese elemento. También podemos definir un valor de retorno predeterminado, en caso de que no se encuentre la clave:

contactos = {'Yan': '1234-5678', 'Pedro': '9999-9999', 'Ana': '8765-4321',
            'Marina': '8877-7788', 'Javier': '8887-7778'}

print(contactos.pop('Marina', 'Contacto no encontrado'))
print(contactos.pop('Catarina', 'Contacto no encontrado'))
print()
print(contactos)

Es el resultado:

8877-7788
Contacto no encontrado

{'Yan': '1234-5678', 'Pedro': '9999-9999', 'Ana': '8765-4321',
  'Javier': '8887-7778'}

¡Todo está bien ahora! Lástima que tengo pocos contactos en la agenda ...

Poniendo dos diccionarios juntos

Le pedí a mi amigo Pedro que me ayudara a aumentar mi agenda agregando algunos amigos más como contactos. Me dio su agenda:

contactos_de_pedro = {'Yan': '1234-5678', 'Fernando':'4345-5434',
                        'Luiza':'4567-7654'}

¿Y entonces? ¿Cómo agregamos todos estos contactos a mi calendario? Podemos intentar hacer uno loop yendo a través de los contactos de Pedro y agregándolos uno por uno:

mis_contatos = {'Yan': '1234-5678', 'Pedro': '9999-9999',
                    'Ana': '8765-4321', 'Javier': '8887-7778'}

contactos_de_pedro = {'Yan': '1234-5678', 'Fernando': '4345-5434',
                        'Luiza': '4567-7654'}

for nombre in contactos_de_pedro:
    mis_contactos[nombre] = contactos_de_pedro[nombre]

print(mis_contactos)

Ahora veamos mi diccionario:

{'Yan': '1234-5678', 'Pedro': '9999-9999', 'Ana': '8765-4321',
  'Javier': '8887-7778', 'Fernando': '4345-5434', 'Luiza': '4567-7654'}

Ok, funcionó! ¿Pero no hay una manera más simple de hacer esto, evitando el ciclo for?

Tenga en cuenta que queremos combinar nuestros dos diccionarios en uno: el primero. Queremos actualizar el primer diccionario para que también contenga los valores del segundo. Para esto, tenemos nuestro propio método: el update(). Podemos reemplazar el bucle con la llamada al método:

mis_contactos.update(contactos_pedro)
print(mis_contactos)

¡Y el resultado sigue siendo correcto, con un código más sucinto!

El problema del prefijo para comprensión del diccionario

Imagine si necesitemos adicionar algum código, por ejemplo él código de algun pais o region como prefijo, por ejemplo el 9. ¿Y ahora? ¿Tendré que usar el método update()para cambiar todos los valores? No tiene sentido…

Lo ideal sería tener una lógica más objetiva, que simplemente copiara todo el diccionario de contactos, pero agregara uno 9 a cada valor. Al principio, una idea es hacer esto con uno for, que debería funcionar, pero ¿existe una forma más simple?

Más sintáctico y elegante que un bucle for tradicional es lo que podemos hacer con lo que ya sabemos por la sintaxis de lista de comprensión, pero esta vez aplicado a los diccionarios de comprensión de diccionario . La idea es la misma y la sintaxis es similar:

mis_contactos_nuevo = {nombre: '9' + mis_contactos[nombre] for nombre in mis_contactos}
print(mis_contactos_nuevo)

Es el resultado:

{'Yan': '91234-5678', 'Pedro': '99999-9999', 'Ana': '98765-4321',
  'Javier': '98887-7778', 'Fernando': '94345-5434', 'Luiza': '94567-7654'}

¡Lo hicimos! ¡Ahora podemos manejar bien nuestro horario!

Para saber mas

Los diccionarios son cambiables

Un detalle que puedes haber notado hasta ahora es que a lo largo de la publicación, generalmente modificamos (ya sea agregando, eliminando o actualizando) el diccionario en el acto, sin la necesidad de crear otro objeto.

Esto se debe a que los diccionarios, como las listas, son modificables . Es importante estar al tanto de esto, para no molestarnos en las posibles complicaciones que la diferencia de mutabilidad implica en los objetos en Python.

Views vs. listas

Usamos el método values()para verificar si el diccionario tenía un valor específico, pero nunca pudimos ver qué devuelve. Vamos a probar:

valores = mis_contactos_nuevo.values()
print(valores)

Aquí llegamos a un punto interesante. Cuando ejecutamos este código en Python 2 , mira lo que aparece

['91234-5678', '99999-9999', '98765-4321', '98887-7778',
  '94345-5434', '94567-7654']

Una lista que contiene los valores, a la derecha. Ahora, en el intérprete de Python 3:

dict_values(['91234-5678', '99999-9999', '98765-4321',
                '98887-7778', '94345-5434', '94567-7654'])

El resultado es similar, pero de un tipo diferente dict_values. ¿Que es eso? Esta clase es lo que llamamos vista de diccionario, que no es más que una ventana a los valores del diccionario.

Views suelen ser ventajosas en comparación con las listas, precisamente porque son solo una apertura, no una estructura en sí mismas. Por lo tanto, siempre están actualizados:

valores = mis_contactos_nuevos.values()
print(valores)

mis_contactos_nuevos['Yan'] = '91122-3344'
print(valores)

En el intérprete de Python 2:

['91234-5678', '99999-9999', '98765-4321', '98887-7778',
  '94345-5434', '94567-7654']

La lista era como la anterior. En Python 3:

dict_values(['911122-3344', '99999-9999', '98765-4321',
                '98887-7778', '94345-5434', '94567-7654'])

La variable valoresactualizada juntos! Además de esta ventaja, también ahorramos memoria con vistas , ya que siempre ocupan el mismo espacio, como una ventana:

print(valores.__sizeof__())

Con la lista en Python 2, el resultado:

112

Ahora, con la view en Python 3:

24

Mucho menos!

El tipo de mapeo en Python

Las tuplas y las listas pueden ayudarnos mucho a organizar nuestros datos en programas, pero a veces necesitamos un tipo más directo y específico para el mapeo basado en la clave y el valor.

Para esta necesidad, en Python tenemos el tipo de diccionario , que es modificable y nos proporciona varios métodos para facilitar la manipulación de datos en esta estructura.

En esta publicación, aprendimos no solo cómo crear un diccionario, sino también cómo acceder a elementos dentro de él, agregar otros, eliminar e incluso unir un diccionario con otro. Otra característica interesante que pudimos explorar es la comprensión del diccionario, que nos permite crear un diccionario poderoso con una sintaxis más simple.

¿Qué tal aprender más sobre Python y sus diversos recursos? Entonces, ¡Mira nuestros cursos de Python para Data Science aquí en Alura!

Artículos de Tecnología > Data Science

En Alura encontrarás variados cursos sobre Data Science. ¡Comienza ahora!

Precios en:
USD
  • USD
  • BOB
  • CLP
  • COP
  • USD
  • PEN
  • MXN
  • UYU

Semestral

  • 271 cursos

    Cursos de Programación, Front End, Data Science, Innovación y Gestión.

  • Videos y actividades 100% en Español
  • Certificado de participación
  • Estudia las 24 horas, los 7 días de la semana
  • Foro y comunidad exclusiva para resolver tus dudas
  • Luri, la inteligencia artificial de Alura

    Luri es nuestra inteligencia artificial que resuelve dudas, da ejemplos prácticos y ayuda a profundizar aún más durante las clases. Puedes conversar con Luri hasta 100 mensajes por semana

  • Acceso a todo el contenido de la plataforma por 6 meses
US$ 65.90
un solo pago de US$ 65.90
¡QUIERO EMPEZAR A ESTUDIAR!

Paga en moneda local en los siguientes países

Anual

  • 271 cursos

    Cursos de Programación, Front End, Data Science, Innovación y Gestión.

  • Videos y actividades 100% en Español
  • Certificado de participación
  • Estudia las 24 horas, los 7 días de la semana
  • Foro y comunidad exclusiva para resolver tus dudas
  • Luri, la inteligencia artificial de Alura

    Luri es nuestra inteligencia artificial que resuelve dudas, da ejemplos prácticos y ayuda a profundizar aún más durante las clases. Puedes conversar con Luri hasta 100 mensajes por semana

  • Acceso a todo el contenido de la plataforma por 12 meses
US$ 99.90
un solo pago de US$ 99.90
¡QUIERO EMPEZAR A ESTUDIAR!

Paga en moneda local en los siguientes países

Acceso a todos
los cursos

Estudia las 24 horas,
dónde y cuándo quieras

Nuevos cursos
cada semana