martes, 22 de junio de 2021

Los Diccionarios en Python

imagen de un diccionario clave:valor


Un diccionario en Python es un objeto (dict) en el que los elementos se almacenan utilizando un sistema basado en el sistema clave:valor o Key:values en inglés. Es decir se asocia a cada clave un determinado valor o valores. 

Un ejemplo de diccionario podría ser el que asociara los países con sus respectivas capitales. En este caso la clave sería el país y su valor la capital. 

midiccionario = {"país":"capital"} ------> {clave : valor, .........., clave : valor}

>>> diccio = {"España":"Madrid","Francia":"Paris","Alemania":"Berlin"}
# para acceder a los valores de un diccionario usamos las claves
>>> print(diccio["España"])
Madrid

Los datos a partir de la version 3.7 de python son ordenados, se pueden modificar, pero lo que no puede ocurrir nunca en un diccionario es que haya dos claves iguales.

Otra forma de definir un dicionario en Python es utilizando un lista con tuplas de dos elementos en la que la primera será la clave y la segunda el valor.

>>> mi_diccionario = dict([("clave1","valor1"), ("clave2", "valor2"), ("clave3", "valor3")])
>>> mi_diccionario
{'clave1': 'valor1', 'clave2': 'valor2', 'clave3': 'valor3'}
E incluso si las claves son strings, es decir texto, también tenemos otra opción para definir un diccionario:

>>> mi_diccionario = dict(clave1="valor1", clave2="valor2")
>>> mi_diccionario
{'clave1': 'valor1', 'clave2': 'valor2'}


Ver los valores asociados a una clave.


Podemos acceder a los elementos de un diccionario refiriéndonos a los valores de su clave entre corchetes [ ]

print(nombre_diccionario[clave])

>>> diccionario = {"España":"Madrid","Francia":"Paris","Alemania":"Berlin"}
>>> print(diccionario["España"])
Madrid

aunque también podemos utilizar el método get

>>> diccionario = {"España":"Madrid","Francia":"Paris","Alemania":"Berlín"}
>>> print(diccionario.get("España"))
Madrid

La diferencia que existe entre ambos métodos es que si no existe la clave en el diccionario en el primero nos dará un error mientras que con get nos dará un None o si definimos su valor opcional nos lo mostrará.

>>> diccionario = {"España":"Madrid","Francia":"Paris","Alemania":"Berlin"}
>>> print(diccionario['Rusia'])
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    print(diccionario['Rusia'])
KeyError: 'Rusia'
>>> print(diccionario.get('Rusia'))
None
>>> print(diccionario.get('Rusia', 'No existe la clave'))
No existe la clave

Otra forma de ver si existe una clave en un diccionario es usando la palabra reservada in. El valor será True si existe o False en caso contrario.

>>> diccionario = {"España":"Madrid","Francia":"Paris","Alemania":"Berlin"}
>>> print("Alemania" in diccionario)
True

Para añadir un registro a un diccionario se hace de una forma muy parecida. Vamos a añadir al diccionario anterior como país Reino Unido y como capital Londres.

>>> diccionario["Reino Unido"] = "Londres"
>>> print(diccionario)
{'España': 'Madrid', 'Francia': 'Paris', 'Alemania': 'Berlín', 'Reino Unido': 'Londres'}

Y si queremos eliminar un elemento utilizamos la función del, o el método pop() o pop(item):

>>> del diccionario["Francia"]
>>> print(diccionario)
{'España': 'Madrid', 'Alemania': 'Berlín', 'Reino Unido': 'Londres'}

El método pop elimina el elemento con la clave especificada:

>>> diccionario.pop('Francia')
>>> print(diccionario)
{'España': 'Madrid', 'Alemania': 'Berlín', 'Reino Unido': 'Londres'}
El método .popitem() elimina el último elemento insertado. (En versiones anteriores a la 3.7 de Python elimina un elemento de forma aleatoria).

>>> diccionario = {"España":"Madrid","Francia":"Paris","Alemania":"Berlín"}
>>> diccionario.popitem()
>>> print(diccionario)
{'España': 'Madrid', 'Francia': 'Paris'}


Longitud de un Diccionario.


Para saber cuantos elementos tiene un diccionario podemos utilizar la función len()


>>> diccionario = {"España":"Madrid","Francia":"Paris","Alemania":"Berlín"}
>>> print(len(diccionario))
3


Elementos de un diccionario. Tipos de datos.


Los valores de los elementos de un diccionario pueden ser de cualquier tipo de datos, incluso otro diccionario:

>>> coches={"marca":"Seat", "electrico":False, "año":1998, "colores":["rojo","blanco","azul"]}
>>> print(coches)
{'marca': 'Seat', 'electrico': False, 'año': 1998, 'colores': ['rojo', 'blanco', 'azul']}

Desde la perspectiva de Python los diccionarios son objetos con el tipo de dato "dict"

<class 'dict'>


Listar las claves, valores o elementos de un diccionario.

El método .keys() nos proporciona una lista con todas las claves del diccionario.

>>> diccionario = {'nombre' : 'Carlos', 'edad' : 22, 'cursos': ['Python','Django','JavaScript'] }
>>> print(diccionario.keys())
dict_keys(['nombre', 'edad', 'cursos'])

y el método .values() nos dará los valores del mismo.

>>> diccionario = {'nombre' : 'Carlos', 'edad' : 22, 'cursos': ['Python','Django','JavaScript'] }
>>> print(diccionario.values())
dict_values(['Carlos', 22, ['Python', 'Django', 'JavaScript']])

Para obtener los elementos de un diccionario podemos realizar una iteración en el diccionario:

>>> diccionario = {'nombre' : 'Carlos', 'edad' : 22, 'cursos': ['Python','Django','JavaScript'] }
# Se podría también iterar sobre:
# for i in diccionario.keys():
# for i in diccionario.values():
# for i in diccionario.items():
>>> for i in diccionario:
      print(i, diccionario[i])

nombre Carlos
edad 22
cursos ['Python', 'Django', 'JavaScript']

Aunque es más eficiente usar el método .items(), que nos devuelve cada el elemento del diccionario, como una tupla dentro de una lista.


Actualizando un diccionario:

El método .update() actualizará un diccionario ya existente con los elementos que le hayamos pasado como argumento. El argumento debe ser un diccionario o un iterable con la estructura clave:valor

>>> diccionario = {'nombre' : 'Carlos', 'edad' : 22, 'cursos': ['Python','Django','JavaScript'] }
>>> diccionario.update({"apellido":"moran"})
>>> print(diccionario["apellido"])
moran

o también podemos añadir un nuevo elemento simplemente usando una nueva clave y su correspondiente valor como vimos anteriormente.


Copiando un diccionario.

No podemos copiar un diccionario simplemente diciendo que diccionario2 = diccionario1 ya que entonces el diccionario2 sería solamente una referencia al diccionario1 y cualquier cambio que hiciéramos en este, automáticamente quedaría hecho en el diccionario2.

Para copiar un diccionario podemos usar el método copy() o también la función de python dict()

>>> diccionario = {"España":"Madrid","Francia":"Paris","Alemania":"Berlin"}
>>> diccionario2 = diccionario.copy()
>>> diccionario3 = dict(diccionario)


Diccionarios Anidados.

Un diccionario puede contener en su interior otros diccionarios, lo cual es bastante habitual. Es lo que se conoce como diccionarios anidados. Veamos un ejemplo:

>>> empleados = {
  "empleado1" : {
    "nombre" : "Antonio",
    "año de incorporación" : 2004
  },
  "empleado2" : {
    "nombre" : "Emilio",
    "año de incorporación" : 2007
  },
  "empleado3" : {
    "nombre" : "Ana",
    "año de incorporación" : 2011
  }
}


Biblioteca Standar Collections y su relación con los diccionarios.


Particularmente  un módulo que me ha resultado muy útil de la biblioteca estándar de Python es "collections".

En el podemos encontrar la clase "Counter". Lo que hace es contar las frecuencias de una colección de elementos que le pasemos como argumento, usualmente strings o listas aunque también le podemos pasar objetos.  Lo mejor es que veamos su funcionamiento con varios ejemplos. 

>>> from collections import Counter
>>> lista = ['pera','manzana','pera','limon','pera','manzana','limon']
>>> print(Counter(lista))
Counter({'pera': 3, 'manzana': 2, 'limon': 2})

Como ves nos devuelve un iterable que contiene un diccionario en el cual están las veces que se repite la fruta en cuestión en la lista que le he pasado. Sirve para contar las veces que se repite un elemento.

>>> from collections import Counter
>>> lista=[1,3,5,4,5,1,2,7,6,7,9,1,0,1]
>>> diccionario_frecuencias = Counter(lista)
>>> print(diccionario_frecuencias)
Counter({1: 4, 5: 2, 7: 2, 3: 1, 4: 1, 2: 1, 6: 1, 9: 1, 0: 1})
>>> diccionario_frecuencias[7]
2
En este otro ejemplo le pasamos una lista de números y luego almacenamos el objeto que nos devuelve Counter a la variable "diccionario_frecuencias" y vemos como podemos consultar cualquier valor escribiendo su clave. En el ejemplo le preguntamos por el número 7 y nos devuelve que se repite 2 veces en la lista.

También podemos encontrar la clase "defaultdict". Básicamente nos sirve para que cuando intentemos acceder a claves que no existen en un diccionario no nos de el error "Keyerror". El argumento para inicializarlo es cualquier objeto que se pueda llamar, ya sea una lista, un entero, un string etc pero sin argumentos.

Veamos un ejemplo del problema.

>>> # Creamos un diccionario vacio.
>>> mi_diccionario = {}
>>> # Añadimos una clave.
>>> mi_diccionario["uno"] = 1
>>> # Si intentamos acceder a una clave que no existe entonces:
>>> mi_diccionario["missing"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'missing'
>>> # Obtenemos un error. Lo intentamos con otra clave.
>>> mi_diccionario["another_missing"].append(4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'another_missing'
Ahora vamos a ver como usando "defaultdict" se nos resuelve el problema.

>>> from collections import defaultdict
>>> mi_diccionario = defaultdict(list) # el argumento sin parentesis 
>>> mi_diccionario["uno"] = 1
>>> mi_diccionario["missing"]
[]
>>> mi_diccionario["another_missing"] = 4
>>> print(mi_diccionario)
defaultdict(<class 'list'>, {'uno': 1, 'missing': [], 'another_missing': 4})
>>> 

Encontrar la clave para el valor máximo en un diccionario.


Imagina que tienes un almacén de fruta. En ese almacén las existencias de cada una de las frutas está almacenadas en un diccionario con la siguiente estructura.

diccionario {"peras":2,"manzanas":5,"naranjas":1}
¿Cómo saber de cual de las frutas es de la que tenemos más existencias? Es sencillo simplemente tenemos que usar la función "max" sobre el diccionario de las siguiente forma:

manzanas


Ordenar un diccionario por clave o por valor.


Usando el ejemplo anterior podemos ordenar un diccionario por sus claves.

diccionario {"peras":2,"manzanas":5,"naranjas":1}
dicionario_ordenado = sorted(diccionario, key = diccionario.get) >>> ['naranjas', 'peras', 'manzanas']
o en base a sus valores. Si queremos en orden descendente usamos el parámetro reverse=True.

diccionario = {"peras":2,"manzanas":5,"naranjas":1}

diccionario_ordenado = sorted(diccionario, key = diccionario.get, reverse=True)
for w in diccionario_ordenado:
    print(w, diccionario[w])
>>>
manzanas 5
peras 2
naranjas 1

Invertir un diccionario. Intercambiar claves por valores y viceversa.

# Diccionario original
dic = {'a':1, 'b':2, 'c':3}
# Diccionario con claves intercambiadas con valores
dic_invertido = {v: k for k,v in dic.items()}
print(dic_invertido)

SALIDA
{1:'a', 2:'b', 3:'c'}


Usar un diccionario para realizar bifurcaciones:

Imagina que quieres construir un menú de opciones en el que dependiendo de lo que seleccione el usuario se haga una cosa u otra. Tendrías que construir un código similar a esto:

# Bifurcaciones usando if.
'''
if acción == 1:
    print("Pulsaste uno")
elif accion == 2:
    print("Pulsaste dos")
elif accion == 3:
    print("Pulsaste tres")
elif accion == 4:
    print("Pulsaste cuatro")
'''

# Bifurcaciones usando un diccionario.

opciones = {1:'uno', 2:'dos', 3:'tres', 4:'cuatro'}
x = int(input("introduzca un valor: "))
print(f'Pulsaste {opciones[x]}')

Pues bien usando diccionarios se nos simplifica bastante el código de la siguiente manera:


Puedes encontrar más información y ejemplos sobre diccionarios en la página web de w3schools.com



No hay comentarios:

Publicar un comentario