El diccionario de Python es la estructura de datos más versátil del lenguaje. Desde Python 3.7, además, mantiene el orden de inserción. Conocer sus métodos y las formas idiomáticas de acceder a sus datos te ahorra código innecesario y evita el KeyError que interrumpe programas en producción.
get() vs corchetes: evitar KeyError
Los corchetes lanzan KeyError si la clave no existe. get() devuelve None (o un valor por defecto) sin lanzar excepción:
config = {"host": "localhost", "puerto": 5432}
# KeyError si la clave no existe
# usuario = config["usuario"] # KeyError: 'usuario'
# get() devuelve None o el valor por defecto
usuario = config.get("usuario") # None
timeout = config.get("timeout", 30) # 30 (valor por defecto)
host = config.get("host", "remoto") # 'localhost' (clave existe)
print(usuario, timeout, host)
# None 30 localhost
setdefault(): obtener o inicializar
setdefault(key, default) devuelve el valor existente si la clave está; si no, la inserta con el valor por defecto y lo devuelve. Es el patrón idiomático para agrupar elementos:
# Agrupar palabras por primera letra
palabras = ["apple", "banana", "avocado", "blueberry", "cherry"]
grupos = {}
for palabra in palabras:
letra = palabra[0]
grupos.setdefault(letra, []).append(palabra)
print(grupos)
# {'a': ['apple', 'avocado'], 'b': ['banana', 'blueberry'], 'c': ['cherry']}
update() y pop()
usuario = {"nombre": "Ana", "edad": 28}
# update() fusiona otro dict (o kwargs) en el existente
usuario.update({"email": "[email protected]", "edad": 29})
print(usuario)
# {'nombre': 'Ana', 'edad': 29, 'email': '[email protected]'}
# pop() elimina y devuelve el valor
email = usuario.pop("email")
sin_email = usuario.pop("telefono", "no disponible") # default para evitar KeyError
print(email, sin_email) # [email protected] no disponible
Dict comprehension
# Cuadrados de 1 a 5
cuadrados = {x: x**2 for x in range(1, 6)}
print(cuadrados) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# Invertir un diccionario
original = {"a": 1, "b": 2, "c": 3}
invertido = {v: k for k, v in original.items()}
print(invertido) # {1: 'a', 2: 'b', 3: 'c'}
# Filtrar: solo mayores de 18
edades = {"Ana": 22, "Luis": 16, "María": 31, "Juan": 15}
adultos = {n: e for n, e in edades.items() if e >= 18}
print(adultos) # {'Ana': 22, 'María': 31}
Fusión con | (Python 3.9+)
# Python 3.9: operador | para fusionar dicts sin modificar
base = {"host": "localhost", "puerto": 5432}
extras = {"usuario": "admin", "puerto": 5433} # puerto sobreescribe
fusionado = base | extras
print(fusionado)
# {'host': 'localhost', 'puerto': 5433, 'usuario': 'admin'}
# |= modifica en sitio
base |= extras
defaultdict: la alternativa a setdefault
from collections import defaultdict
# Nunca lanza KeyError: crea el valor por defecto automáticamente
contador = defaultdict(int)
for letra in "programacion":
contador[letra] += 1
print(dict(sorted(contador.items())))
# {'a': 3, 'c': 1, 'g': 1, 'i': 1, 'm': 1, 'n': 1, 'o': 2, 'p': 1, 'r': 2}
El método get() con valor por defecto y las dict comprehensions son las herramientas más usadas en el día a día. setdefault() y defaultdict son la solución idiomática para construir dicts de listas o contadores desde cero.
