¿Cómo y cuándo debería usar Defaultdict en Python?

En este tutorial, aprenderá a usar defaultdict del módulo de colecciones de Python, para manejar mejor KeyErrors, cuando trabaje con diccionarios de Python.

En Python, un diccionario es una poderosa estructura de datos integrada que almacena datos en pares clave-valor. Utilizará las teclas para acceder al diccionario y acceder a los valores.

Sin embargo, cuando tiene varios diccionarios en su secuencia de comandos de Python que se modifican durante la ejecución del código, a menudo se encontrará con KeyErrors. Y hay algunas maneras diferentes de manejarlos.

En este tutorial, aprenderá:

  • Qué son KeyErrors y por qué surgen
  • Cómo manejar KeyErrors
  • Cómo usar el dictado predeterminado de Python, una subclase que hereda de la clase de dictado incorporada, para manejar mejor las claves que faltan

¡Vamos a empezar!

¿Qué son los errores de clave en Python?

Al definir un diccionario de Python, debe tener cuidado de asegurarse de lo siguiente:

  • Las claves deben ser únicas, sin ninguna repetición.
  • Cuando use un iterable existente como las claves de un diccionario, debería preferir usar una colección inmutable como una tupla.

Entonces, una clave es válida solo si está presente en el diccionario; de lo contrario, conduce a KeyErrors.

Considere el siguiente diccionario, libros_autores, en el que las claves son los nombres de los libros y los valores son los nombres de los autores.

Puede codificar junto con este tutorial en un REPL de Python.

books_authors = {
    'Deep Work':'Cal Newport',
    'Hyperfocus':'Chris Bailey',
    'Pivot':'Jenny Blake',
    'The Happiness Equation':'Neil Pasricha'
}

Puede utilizar la clave (nombre del libro) para acceder al nombre del autor.

books_authors['Hyperfocus']
'Chris Bailey'

Para acceder a todos los pares clave-valor en el diccionario, puede llamar al método items() en el objeto del diccionario, como se muestra a continuación:

for book,author in books_authors.items():
  print(f"'{book}' by {author}")
'Deep Work' by Cal Newport
'Hyperfocus' by Chris Bailey
'Pivot' by Jenny Blake
'The Happiness Equation' by Neil Pasricha

Si intenta acceder al valor de una clave que no está presente en el diccionario, el intérprete de Python genera un KeyError. Nos encontramos con KeyError cuando intentamos acceder al valor de claves que no existen, es decir, ‘Grit’ y ‘inexistente key’.

books_authors['Grit']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-6-e1a4486f5ced> in <module>
----> 1 books_authors['Grit']

KeyError: 'Grit'
books_authors['non-existent-key']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-7-a3efd56f69e5> in <module>
----> 1 books_authors['non-existent-key']

KeyError: 'non-existent-key'

Entonces, ¿cómo maneja KeyErrors en Python?

Hay algunas formas de hacerlo, y las aprenderemos en la siguiente sección.

Cómo manejar KeyErrors en Python

Aprendamos cómo manejar KeyErrors usando:

  • Declaraciones condicionales if-else
  • Bloques Try-except
  • El método del diccionario .get()

#1. Uso de sentencias condicionales If-Else

Una de las formas más simples de manejar KeyErrors en Python es usar las declaraciones condicionales if-else.

En Python, las declaraciones if-else tienen la siguiente sintaxis general:

 if condition:
 	# do this 
 else:
    # do something else 
  • Si la condición es verdadera, se ejecutan las declaraciones en el cuerpo if y
  • Si la condición es Falsa, se ejecutan las declaraciones en el cuerpo else.

En este ejemplo, la condición es verificar si la clave está presente en el diccionario.

Si la clave está presente en el diccionario, el operador de entrada devolverá True, y si el cuerpo se ejecutará, imprimirá el valor correspondiente.

key = 'The Happiness Equation'
if key in books_authors:
  print(books_authors[key])
else:
  print('Sorry, this key does not exist!')

# Output
# Neil Pasricha

Si la clave no está presente en el diccionario, el operador in devuelve False y se ejecutará el cuerpo else. Imprime un mensaje de que la clave no está presente.

key = 'non-existent-key'
if key in books_authors:
  print(books_authors[key])
else:
  print('Sorry, this key does not exist!')

# Output
# Sorry, this key does not exist!

#2. Uso de declaraciones Try-Except

Otro método común para manejar KeyError es usar las declaraciones try-except en Python.

Lea el siguiente bloque de código:

key = 'non-existent-key'
try:
  print(books_authors[key])
except KeyError:
  print('Sorry, this key does not exist!')
  • El bloque try intenta recuperar el valor correspondiente a la clave proporcionada.
  • Si la clave no está presente, el intérprete genera un KeyError que se maneja como una excepción dentro del bloque excepto.

#3. Usando el método .get()

En Python, puede usar el método de diccionario incorporado .get() para manejar las claves que faltan.

La sintaxis general para usar el método get() es dict.get(key,default_value) donde dict es un objeto de diccionario válido en Python.

– Si la clave está presente en el diccionario, el método get() devuelve el valor.
– De lo contrario, devuelve el valor predeterminado.

En este ejemplo, claves es una lista de claves a cuyos valores nos gustaría acceder. Recorremos la lista de claves para recuperar los valores correspondientes del diccionario books_authors.

Aquí, hemos usado el método .get() con ‘No existe’ como valor predeterminado.

keys = ['Grit','Hyperfocus','Make Time','Deep Work']
for key in keys:
  print(books_authors.get(key,'Does not exist'))

En el código anterior:

  • Para las claves que están presentes en el diccionario books_authors, el método .get() devuelve los valores correspondientes.
  • Cuando las claves no existen, en este caso, ‘Grit’ y ‘Make Time’, el método .get() devuelve el valor predeterminado ‘No existe’.
# Output

Does not exist
Chris Bailey
Does not exist
Cal Newport

Todos los métodos anteriores nos ayudan a manejar los errores clave. Sin embargo, son detallados y requieren que manejemos explícitamente las claves que faltan. Puede simplificar este proceso utilizando un diccionario predeterminado en lugar de un diccionario normal.

Predeterminado en Python

El predeterminadodict es una subclase de la clase de diccionario (dict). Entonces hereda el comportamiento de un diccionario de Python. Además, también maneja las claves que faltan de forma nativa.

El dictado predeterminado es un tipo de datos de contenedor que está integrado en la biblioteca estándar de Python, dentro del módulo de colecciones.

Así que tienes que importarlo a tu entorno de trabajo:

from collections import defaultdict

Aquí está la sintaxis general para usar defaultdict:

defaultdict(default_factory)

Puede especificar un invocable como int, float o list como el atributo default_factory. Si no proporciona un valor para default_factory, el valor predeterminado es Ninguno.

Cuando la clave que está buscando no está presente, se activa el método __missing__() e infiere el valor predeterminado de default_factory. A continuación, devuelve este valor predeterminado.

En resumen:

  • En Python, un dictamen predeterminado devuelve el valor predeterminado cuando la clave no está presente.
  • También agrega este par clave-valor predeterminado al diccionario, que luego puede modificar.

Ejemplos de Python por defecto

A continuación, codificaremos algunos ejemplos para comprender cómo funciona Python defaultdict.

Defaultdict en Python con valor entero predeterminado

Primero, importa defaultdict desde el módulo de colecciones.

from collections import defaultdict
import random

Vamos a crear precios predeterminados.

prices = defaultdict(int)

Ahora llenamos el diccionario de precios usando los elementos de la lista de frutas como claves. Y tomamos muestras aleatorias de valores de la lista de precios para obtener los valores.

price_list = [10,23,12,19,5]
fruits = ['apple','strawberry','pomegranate','blueberry']

for fruit in fruits:
  prices[fruit] = random.choice(price_list)

Echemos un vistazo a los pares clave-valor en el dictamen predeterminado de precios.

print(prices.items())
dict_items([('apple', 12), ('blueberry', 19), ('pomegranate', 5), ('strawberry', 10)])

Al igual que un diccionario normal de Python, puede acceder a los valores de los precios predeterminados usando las teclas:

prices['apple']
# 23

Ahora, intentemos acceder al precio de una fruta que no está presente, digamos, ‘naranja’. Vemos que devuelve el valor por defecto de cero.

prices['orange']
# 0

Si imprimimos el diccionario, vemos que se ha agregado una nueva clave ‘naranja’ con el valor entero predeterminado de cero.

print(prices.items())
dict_items([('apple', 12), ('blueberry', 19), ('pomegranate', 5), ('strawberry', 10), ('orange', 0)])

Defaultdict en Python con List como valor predeterminado

Definamos Students_majors como un dictado predeterminado de listas. Los nombres de los mayores son las claves. Y los valores son las listas de estudiantes que cursan cada una de las carreras, como matemáticas, economía, informática y más.

from collections import defaultdict
students_majors = defaultdict(list)

Si intentamos acceder a la lista de alumnos correspondiente a ‘Economía’, defaultdict devuelve una lista vacía; sin errores clave!

students_majors['Economics']
# []

Ahora tenemos una lista vacía asignada a la especialidad de ‘Economía’. Entonces ahora podemos agregar elementos a esta lista usando el método de lista .append().

students_majors['Economics'].append('Alex')

Se ha creado una entrada para ‘Economía’ en el diccionario predeterminado Students_majors.

print(students_majors)
defaultdict(<class 'list'>, {'Economics': ['Alex']})

¡Puede agregar más estudiantes a la lista de asignación a la especialidad de Economía, agregar una nueva especialidad y mucho más!

students_majors['Economics'].append('Bob')
students_majors['Math'].append('Laura')
print(students_majors)
defaultdict(<class 'list'>, {'Economics': ['Alex', 'Bob'], 'Math': ['Laura']})

Conclusión

Espero que este tutorial te haya ayudado a comprender cómo y cuándo debes usar defaultdict en Python. Después de ejecutar los ejemplos de código en este tutorial, puede intentar usar defaultdict como la estructura de datos preferida en sus proyectos cuando sea necesario.

Aquí hay un resumen de lo que has aprendido en este tutorial.

  • Cuando trabaje con un diccionario de Python, a menudo se encontrará con KeyErrors.
  • Para manejar tales KeyErrors, puede usar algunos métodos detallados. Puede usar sentencias condicionales, bloques try-except o el método .get(). Pero el tipo de datos predeterminado en el módulo de colecciones puede simplificar este manejo de KeyError.
  • Puede usar defaultdict(default_factory) donde default_factory es un invocable válido.
  • Cuando la clave no está presente en el dictado predeterminado, el valor predeterminado (inferido de fábrica_predeterminada) y la clave se agregan al dictado predeterminado.

A continuación, consulte el tutorial sobre la función de mapa de Python.