Diccionarios#

Introducción#

En esta lección revisamos los conjuntos, los cuales son iterables que se basa en el paradigma clave-valor, que resultan esenciales para el tratamiento avanzado de datos. Un diccionario tiene una estructura a un archivo de tipo JSON, aunque son estructuras de datos diferentes. Por otro lado, si aprende manipular los diccionarios en Python, ya sabe el 95% de lo que son los archivos JSON.

Diccionarios #

Los diccionarios se distinguen por dos conceptos claves: están encapsulado en {} y poseen el concepto de llave e ítem.

Consideraciones importantes:

En contraste con las listas, los elementos del diccionario no se acceden vía índices, sino vía llaves (keys) que se definen.

Miremos el siguiente ejemplo:

Rios = {
...     'Leticia' : 'Amazonas',
...     'Montería': 'Sinu',
...     'Bogotá'  : 'Bogotá',
...     'San Gil': 'Fonce',
...     'Honda'  : 'Magdalena'
... }

print(Rios)
{'Leticia': 'Amazonas', 'Montería': 'Sinu', 'Bogotá': 'Bogotá', 'San Gil': 'Fonce', 'Honda': 'Magdalena'}

Note lo que ocurre cuando intentamos acceder por medio de índices (posiciones):

print(Rios[0])
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/tmp/ipykernel_2607/3953923098.py in <module>
----> 1 print(Rios[0])

KeyError: 0
print(Rios['Montería'])
Sinu

También es posible crear un diccionario usando la función por defecto (built-in) dict(), usando una lista de tuplas:

my_dic=dict([
             ('Colores', ['Negro','Rojo','Azul']),
             ('Animales', 'Gato'),
             ('Calzado', ['Botas','Botines','Deportivos','Sandalias'])
            ])

print(my_dic)
{'Colores': ['Negro', 'Rojo', 'Azul'], 'Animales': 'Gato', 'Calzado': ['Botas', 'Botines', 'Deportivos', 'Sandalias']}

Veamos el tipo de dato que es un diccionario.

print(type(my_dic))
<class 'dict'>

Veamos por ejemplo, los ítems que pertenecen a la llave Colores

print(my_dic['Colores'])
['Negro', 'Rojo', 'Azul']

Una vez ingresado a los ítem del diccionario, en caso de ser listas, podemos acceder a sus elementos tal cual lo hacemos con las listas (por sus índices)

print(my_dic['Colores'][1])
Rojo
print('Ví pasar un',my_dic['Animales'],'con',my_dic['Calzado'][0],'de color',my_dic['Colores'][0])
Ví pasar un Gato con Botas de color Negro

Nota: Si las llaves son strings sencillas (sin espacios), también es posible definir un diccionario de la siguiente manera:

my_dic=dict(
             Colores = ['Negro','Rojo','Azul'],
             Animales= 'Gato',
             Calzado =['Botas','Botines','Deportivos','Sandalias']
            )

print(my_dic)
{'Colores': ['Negro', 'Rojo', 'Azul'], 'Animales': 'Gato', 'Calzado': ['Botas', 'Botines', 'Deportivos', 'Sandalias']}

Claro está, si se intenta acceder a una llave incorrecta, obtendremos el siguiente error:

print(my_dic['Valor'])
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-35-fe7f2260447b> in <module>
----> 1 print(my_dic['Valor'])

KeyError: 'Valor'

Podemos agregar, modificar y eliminar valores de un diccionario:

Agregar valores:#

my_dic['Valor']=['20','50','12']
print(my_dic)
{'Colores': ['Negro', 'Rojo', 'Azul'], 'Animales': 'Gato', 'Calzado': ['Botas', 'Botines', 'Deportivos', 'Sandalias'], 'Valor': ['20', '50', '12']}

Modificar valores:#

my_dic['Colores']='Negro'
print(my_dic)
{'Colores': 'Negro', 'Animales': 'Gato', 'Calzado': ['Botas', 'Botines', 'Deportivos', 'Sandalias'], 'Valor': ['20', '50', '12']}

Eliminar valores:#

del my_dic['Valor']
print(my_dic)
{'Colores': 'Negro', 'Animales': 'Gato', 'Calzado': ['Botas', 'Botines', 'Deportivos', 'Sandalias']}

La razón por la cuál no es permitido acceder a los ítems de los diccionarios con índices, es que ellos mismos pueden ser las llaves:

d = {135: 'Coco', 1: 'Urban_Sound8k', 2: 'Mnist', 3: 'CheXpert'}
print(d)
{135: 'Coco', 1: 'Urban_Sound8k', 2: 'Mnist', 3: 'CheXpert'}
d[135]
'Coco'

Puede ser confuso al principio, confundir estas llaves con índices. Incluso se podría pensar en tomar rebanadas de él sin éxito o agregar valores como se hace en las listas:

#d[0:2]

Ejercicio:

Investigue que significa unhashable. Busque la función hash() y úsela en este contexto.

#d.append('Yolo')

Propiedades de los diccionarios#

Dinámicos#

Este concepto es muy importante, pues resalta la capacidad de un diccionario en incrementar su tamaño sin generar error:

#Generar diccionario vacío
persona = {}
print(type(persona))

# Agregar llaves y sus definiciones (items)
persona['Nombre'] = 'Gengis'
persona['Apellido'] = 'Khan'
persona['Edad'] = 23
persona['Esposa'] = ['Börte Qatun','Yesugen','Qulan Qatun','Möge Qatun','Juerbiesu','Ibaqa Beki']
persona['Hijos'] = 'En estudio'
persona['Mascotas'] = {'Perro': 'Wahadi', 'Gato': 'Gotze','Leon':'Pichirilo'}

print(persona)
print('Hijos de',persona['Nombre'],':',persona['Hijos'])
<class 'dict'>
{'Nombre': 'Gengis', 'Apellido': 'Khan', 'Edad': 23, 'Esposa': ['Börte Qatun', 'Yesugen', 'Qulan Qatun', 'Möge Qatun', 'Juerbiesu', 'Ibaqa Beki'], 'Hijos': 'En estudio', 'Mascotas': {'Perro': 'Wahadi', 'Gato': 'Gotze', 'Leon': 'Pichirilo'}}
Hijos de Gengis : En estudio

Nota

Del ejemplo anterior se puede observar que los diccionarios pueden contener diccionarios en su interior:

print(persona['Mascotas'])
{'Perro': 'Wahadi', 'Gato': 'Gotze', 'Leon': 'Pichirilo'}
print(persona['Mascotas']['Perro'])
Wahadi

Llaves:#

No hay restricciones en la forma de definir las llaves:

foo = {42: 'aaa', 2.78: 'bbb', False: 'cc'}
foo[False]
'cc'
d = {int: 1, float: 2, bool: 3}

d[int]
1

Sin embargo, las llaves son únicas y no se pueden repetir (como un diccionario clásico al que estamos acostumbrados):

foo = {42: 'aaa', 2.78: 'bbb', False: 'cc',False:'dodo'}
foo
{42: 'aaa', 2.78: 'bbb', False: 'dodo'}

Ejercicio#

Defina un diccionario de al menos 4 llaves de tal manera que esas llaves sean tuplas. Acceda a cada elemento. ¿Puede hacer lo mismo para una llave que sea definida como lista o diccionario?

Operadores y Métodos:#

Es posible utilizar algunos operadores sobre los diccionarios para verificar su estado (por ejemplo, si están o no están disponibles sin generar errores):

'Animales' in my_dic
True
'Colores' not in my_dic
False

También podemos usar lógica aristotélica (tablas de verdad) para chequear cosas sin tener errores:

#my_dic['Valor']
#'Valor' in my_dic and my_dic['Valor']

len() sobre diccionarios#

print(my_dic)

print("\nEl diccionario tiene",len(my_dic),'llaves')
{'Colores': 'Negro', 'Animales': 'Gato', 'Calzado': ['Botas', 'Botines', 'Deportivos', 'Sanadalias']}

El diccionario tiene 3 llaves

Métodos#

d.clear()#
print(d)
d.clear()
print(d)
{<class 'int'>: 1, <class 'float'>: 2, <class 'bool'>: 3}
{}

Una vez ingresado a los ítem del diccionario, en caso de ser listas, podemos acceder a sus elementos tal cual lo hacemos con las listas (por sus índices)

d.get(<key>[, <default>])#
print(my_dic.get('Colores'))
Negro
print(persona.get('Esposa'))
['Börte Qatun', 'Yesugen', 'Qulan Qatun', 'Möge Qatun', 'Juerbiesu', 'Ibaqa Beki']
Ejercicio#

¿Qué significa default?

d.items()#
print(my_dic.items())
dict_items([('Colores', 'Negro'), ('Animales', 'Gato'), ('Calzado', ['Botas', 'Botines', 'Deportivos', 'Sanadalias'])])
print(list(my_dic.items()))
[('Colores', 'Negro'), ('Animales', 'Gato'), ('Calzado', ['Botas', 'Botines', 'Deportivos', 'Sanadalias'])]
list(my_dic.items())[0][1]
'Negro'

También existen otros métodos útiles. ¡Averigua para que sirve cada uno!

  • d.keys()

  • d.values()

  • d.pop(<key>[, <default>])

  • d.popitem()

  • d.update(<obj>)

Ejercicio#

A partir de las siguientes líneas de código, entienda lo que hace cada uno de los métodos y cree sus propio ejemplo de mayor complejidad.

print(my_dic)
{'Colores': 'Negro', 'Animales': 'Gato', 'Calzado': ['Botas', 'Botines', 'Deportivos', 'Sanadalias']}
print(my_dic.keys())
print(my_dic.values())
print(my_dic.pop('Colores'))
print(my_dic)
print(my_dic.popitem())
print(my_dic)
print(my_dic.update(persona))
dict_keys(['Colores', 'Animales', 'Calzado'])
dict_values(['Negro', 'Gato', ['Botas', 'Botines', 'Deportivos', 'Sandalias']])
Negro
{'Animales': 'Gato', 'Calzado': ['Botas', 'Botines', 'Deportivos', 'Sandalias']}
('Calzado', ['Botas', 'Botines', 'Deportivos', 'Sandalias'])
{'Animales': 'Gato'}
None

char2int#

Como último ejemplo construimos un diccionario para el alfabeto, de tal manera que dado un caracter retorne un código asociado.

alfabeto = 'abcdefghijklmnñopqrstuvwxyz'
alfaL = []
for j in alfabeto:
    alfaL.append(j)


char2int = {}
num = list(range(len(alfabeto)))

for car,val in zip(alfaL, num):
    char2int[car] = num[val]

print(char2int)
print('\n')
print('char2int[\'c\']=',char2int['c'])
{'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'ñ': 14, 'o': 15, 'p': 16, 'q': 17, 'r': 18, 's': 19, 't': 20, 'u': 21, 'v': 22, 'w': 23, 'x': 24, 'y': 25, 'z': 26}


char2int['c']= 2

Métodos de los diccionarios#

Método

Descripción

clear()

Elimina todos los elementos del diccionario.

copy()

Devuelve una copia poco profunda del diccionario.

get(clave[,valor])

Devuelve el valor de la clave. Si no existe, devuelve el valor valor si se indica y si no, None.

items()

Devuelve una vista de los pares clave: valor del diccionario.

keys()

Devuelve una vista de las claves del diccionario.

pop(clave[,valor])

Devuelve el valor del elemento cuya clave es clave y elimina el elemento del diccionario. Si la clave no se encuentra, devuelve valor si se proporciona. Si la clave no se encuentra y no se indica valor, lanza la excepción KeyError.

popitem()

Devuelve un par (clave, valor) aleatorio del diccionario. Si el diccionario está vacío, lanza la excepción KeyError.

setdefault(clave[,valor])

Si la clave está en el diccionario, devuelve su valor. Si no lo está, inserta la clave con el valor valor y lo devuelve (si no se especifica valor, por defecto es None).

update(iterable)

Actualiza el diccionario con los pares clave: valor del iterable.

values()

Devuelve una vista de los valores del diccionario.

Tips para manipulación de diccionarios#

Mezclar dos diccionarios#

dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}

dict3 = {**dict1, **dict2}

print(dict3)
{'a': 1, 'b': 2, 'c': 3, 'd': 4}

Hacer la unión de dos diccionarios.#

Disponible desde Python 3.9

dict1 = {'a':1, 'b':2}
dict2 = {'c':3, 'b':4}

dict3 = dict1 | dict2
print(dict3)

{‘a’: 1, ‘b’: 4, ‘c’: 3}

Chequear si una clave existe en un diccionario#

dict1 = {'a': 1, 'b': 2}

print('a' in dict1)
print('c' in dict1)
True
False

Remover un item de un diccionario#

Revise las siguientes tres salidas y desarrolle su propio ejemplo.

dict1 = {‘a’: 1, ‘b’: 2}

print(dict1.pop(‘a’)) print(dict1.pop(‘c’, ‘Missing Key’)) print(dict1.pop(‘d’))

Diccionarios por Comprensión#

dict1 = {i:i**2 for i in range(1,11)}
print(dict1)
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81, 10: 100}

Eliminar items vacios (None) en un diccionario#

dict1 = {'a': 'manzana', 'b': 'banano', 'c':None}

dict1 = {key:value for (key, value) in dict1.items() if value is not None}
print(dict1)
{'a': 'manzana', 'b': 'banano'}

Uso de get para acceder a un ítem en un diccionario#

Observe que con el uso de get no se genera un error cuando se intenta accesar una clave que no existe. En ese caso se recibe el valor None. Por el contrario se accesa directamente por la clave, se obtiene un error si la clave no existe en el diccionario.

dict1 = {'a':1, 'b':2}

print(dict1.get('c'))
print(dict1['c'])

# Returns: None
# Returns: KeyError
None
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-68-035bdafe920c> in <module>
      2 
      3 print(dict1.get('c'))
----> 4 print(dict1['c'])
      5 
      6 # Returns: None

KeyError: 'c'

Filtrar un diccionario#

Se pueden obtener los ítems en un diccionario que cumplen con un criterio. En ejemplo se filtran las personas que miden 170 cm o más.

alturas = {'John': 175, 'Luis': 150, 'Carlos': 155, 'María': 170}

alto = {key:value for (key, value) in alturas.items() if value >= 170}

print(tall)
{'John': 175, 'María': 170}

Iterando en un diccionario un diccionario#

Vamos iterar a lo largo de un diccionario, primero por las claves y luego por los valores.

# creamos el diccionario

salarios = {'León': 175, 'Luis': [150, 100], 'Carlos': 155, 'Angel': None}
print(salarios)
{'León': 175, 'Luis': [150, 100], 'Carlos': 155, 'Angel': None}
# recorremos por claves

for salario in salarios:
    print(salario)
León
Luis
Carlos
Angel
# de nuevo por claves
for persona in salarios.keys():
    print(persona)
León
Luis
Carlos
Angel
# recorremos por valores
for salario in salarios.values():
    print(salario)
175
[150, 100]
155
None