▷ Diccionarios en Python — 12 trucos que casi nadie usa 2026

Diccionarios en Python — 12 trucos que casi nadie usa

Los diccionarios son probablemente la estructura de datos más útil de Python. Más que las listas. Y sin embargo, casi todo el mundo los usa con cuatro métodos contados (d["clave"], d.get(), d.keys(), for clave, valor in d.items()) y se pierde un montón de cosas que ya están en el lenguaje, gratis, listas para usar.

En esta entrada te enseño 12 trucos que mejoran de verdad tu código diario con diccionarios. Nada de tonterías de tutorial — patrones que vas a usar la próxima semana.

Si te encuentras escribiendo if clave in d: d[clave].append(...) cada dos por tres, esta entrada es para ti.

1. dict.get() con valor por defecto

Antes de tocar nada, lo más básico bien hecho. Si necesitas leer una clave que podría no existir, no escribas:

if "edad" in usuario:
    edad = usuario["edad"]
else:
    edad = 0

Escribe:

edad = usuario.get("edad", 0)

Si la clave no existe, devuelve el segundo argumento (0). Sin error, sin if, una línea. Si lo omites, devuelve None.

💡 Ojo: usuario["edad"] lanza KeyError. usuario.get("edad") devuelve None. Saber cuál usar te ahorra horas de bugs.

2. dict.setdefault() para inicializar listas anidadas

Patrón mil veces visto: agrupar elementos por categoría.

peliculas = [
    ("Inception", "scifi"),
    ("Heat", "thriller"),
    ("Arrival", "scifi"),
]

por_genero = {}
for titulo, genero in peliculas:
    if genero not in por_genero:
        por_genero[genero] = []
    por_genero[genero].append(titulo)

Lo mismo con setdefault:

por_genero = {}
for titulo, genero in peliculas:
    por_genero.setdefault(genero, []).append(titulo)

setdefault(clave, []).append(...): si la clave no existe la crea con [], devuelve la lista (nueva o existente), y le hace .append(). Limpio.

3. collections.defaultdict — la versión profesional del truco anterior

Cuando vas a hacer ese patrón muchas veces, defaultdict es aún más limpio:

from collections import defaultdict

por_genero = defaultdict(list)
for titulo, genero in peliculas:
    por_genero[genero].append(titulo)

defaultdict(list) significa “si una clave no existe al accederla, créala con una lista vacía”. Y con defaultdict(int) puedes hacer contadores en una línea.

votos = ["sí", "no", "sí", "sí", "no"]
contador = defaultdict(int)
for v in votos:
    contador[v] += 1
# defaultdict(<class 'int'>, {'sí': 3, 'no': 2})

Aunque para contar lo siguiente es aún mejor.

📥 Llévate el cheatsheet de Python (gratis)

PDF de 6 páginas con lo esencial: tipos, condicionales, bucles, estructuras de datos, funciones y los errores que más vas a cometer. Para tener al lado mientras programas.

Sin spam. Te apuntas a la lista, descargas el cheatsheet y recibes contenido de Python cada semana.

4. collections.Counter — contar cosas en una línea

Counter es una subclase de dict que cuenta elementos por ti:

from collections import Counter

palabras = ["python", "java", "python", "go", "python", "java"]
c = Counter(palabras)
# Counter({'python': 3, 'java': 2, 'go': 1})

print(c.most_common(2))
# [('python', 3), ('java', 2)]

Cuenta automático, ordenado por frecuencia con most_common(N). Útil para análisis rápidos: “¿qué palabra aparece más?”, “¿qué error es más frecuente?”, “¿qué usuario hace más peticiones?”.

5. Mergear dos diccionarios con | (Python 3.9+)

Si quieres combinar dos diccionarios:

defaults = {"tema": "oscuro", "idioma": "es", "fontsize": 14}
usuario = {"idioma": "en", "fontsize": 16}

config = defaults | usuario
# {"tema": "oscuro", "idioma": "en", "fontsize": 16}

Lo de la derecha gana en colisiones. Antes había que hacer {**defaults, **usuario}. Ahora con | queda más limpio.

Tip-friki: defaults |= usuario modifica defaults in-place, equivalente a defaults.update(usuario). Útil cuando ya tienes un dict y quieres parchear sobre él.

6. Dict comprehensions

Igual que las list comprehensions pero para diccionarios:

# Diccionario de cuadrados
cuadrados = {n: n**2 for n in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# Invertir un diccionario (claves ↔ valores)
original = {"a": 1, "b": 2, "c": 3}
invertido = {v: k for k, v in original.items()}
# {1: "a", 2: "b", 3: "c"}

# Filtrar entradas
edades = {"Ana": 30, "Luis": 17, "Marta": 22, "Pedro": 15}
mayores = {nombre: edad for nombre, edad in edades.items() if edad >= 18}
# {"Ana": 30, "Marta": 22}

💡 ¿Más patrones de comprehensions? Mira list comprehensions en Python.

7. Iterar clave + valor con .items()

Lo básico bien hecho. No hagas:

for clave in d:
    print(clave, d[clave])    # ❌ accesos extra

Haz:

for clave, valor in d.items():
    print(clave, valor)        # ✓ una sola pasada

Más rápido y mucho más legible. Si solo necesitas claves, for k in d:. Si solo valores, for v in d.values():.

8. Comprobar pertenencia con in (no con .keys())

Algo que mucha gente sigue escribiendo mal:

if "Ana" in d.keys():    # ❌ funciona pero es redundante
    ...

if "Ana" in d:           # ✓ exactamente lo mismo, más limpio
    ...

in sobre un dict comprueba claves por defecto. Si quieres comprobar valores, sí necesitas if "España" in d.values():.

9. Desempaquetar un dict en argumentos con **

Si tienes un dict y quieres pasar cada clave como argumento por nombre:

def crear_pelicula(titulo, año, genero):
    print(f"{titulo} ({año}) — {genero}")

datos = {"titulo": "Inception", "año": 2010, "genero": "scifi"}
crear_pelicula(**datos)
# Inception (2010) — scifi

**datos desempaqueta el dict como si hubieras escrito titulo="Inception", año=2010, genero="scifi". Patrón muy útil cuando vienes con datos de JSON o de la BBDD.

💡 Para entenderlo a fondo: *args y **kwargs en Python.

10. Diccionarios mantienen el orden de inserción (Python 3.7+)

Antes los dicts no garantizaban orden. Ahora . El orden de inserción se mantiene:

ranking = {}
ranking["Ana"] = 95
ranking["Luis"] = 88
ranking["Marta"] = 91

for nombre, puntos in ranking.items():
    print(nombre, puntos)
# Ana 95
# Luis 88
# Marta 91

Sirve para ordenar y mantener orden temporal de eventos. Si necesitas ordenar por valor:

top = dict(sorted(ranking.items(), key=lambda kv: kv[1], reverse=True))
# {"Ana": 95, "Marta": 91, "Luis": 88}

sorted(d.items(), key=lambda kv: kv[1]) ordena por valor. Con reverse=True, descendente.

11. dict.pop() con valor por defecto

Como get(), pero eliminando la clave del dict si existe:

config = {"tema": "oscuro", "idioma": "es", "deprecated_flag": True}

flag = config.pop("deprecated_flag", False)
# config ahora no tiene la clave 'deprecated_flag'
# flag = True

flag2 = config.pop("inexistente", False)
# flag2 = False, no lanza KeyError

Útil para “extraer y limpiar de paso”, típico al normalizar datos de entrada.

12. dict.fromkeys() — crear un dict desde una lista de claves

Cuando quieres inicializar un dict con muchas claves al mismo valor:

campos = ["nombre", "email", "telefono", "direccion"]
formulario = dict.fromkeys(campos, "")
# {"nombre": "", "email": "", "telefono": "", "direccion": ""}

contadores = dict.fromkeys(["A", "B", "C"], 0)
# {"A": 0, "B": 0, "C": 0}

⚠️ Ojo: si usas un valor mutable (lista, dict) como default, todas las claves comparten la misma referencia. dict.fromkeys(["a", "b"], []) te da un dict donde mutar la lista de “a” muta también la de “b”. Para eso, usa una comprehension: {c: [] for c in claves}.

Errores típicos al usar diccionarios

# 1. Acceder con [] cuando podría no existir
nombre = usuario["nombre"]   # ❌ KeyError si no existe
nombre = usuario.get("nombre", "Anónimo")   # ✓

# 2. Modificar el dict mientras se itera
for clave in d:
    if d[clave] is None:
        del d[clave]         # ❌ RuntimeError: dictionary changed size during iteration

# Forma correcta:
for clave in list(d):        # itera una copia
    if d[clave] is None:
        del d[clave]
# o:
d = {k: v for k, v in d.items() if v is not None}

# 3. Confundir d.keys() con list(d.keys())
keys = d.keys()    # vista dinámica del dict; cambia si el dict cambia
keys = list(d.keys())   # snapshot, no cambia con el dict

# 4. Usar listas como claves de dict
d = {[1, 2]: "algo"}   # ❌ TypeError: las listas no son hashables
d = {(1, 2): "algo"}   # ✓ tuplas sí lo son

Resumen — los 12 trucos en una mirada

# Truco Para qué
1 d.get(k, default) Leer con valor por defecto sin KeyError
2 d.setdefault(k, []).append(x) Inicializar y añadir en una línea
3 defaultdict(list) Mismo patrón, aún más limpio cuando se repite
4 Counter(iterable) Contar frecuencias en una línea
5 d1 \| d2 Mergear dos dicts (Python 3.9+)
6 {k: v for ... in ...} Dict comprehensions
7 for k, v in d.items(): Iterar clave-valor en una pasada
8 if k in d: Comprobar pertenencia (no .keys())
9 funcion(**dict) Desempaquetar dict como argumentos
10 Orden de inserción garantizado Útil para ordenar y para sorted()
11 d.pop(k, default) Extraer y eliminar con default
12 dict.fromkeys(claves, valor) Inicializar muchas claves a la vez

¿Te ha valido esto?

Si te ha resultado útil, llévate el cheatsheet de Python en PDF — 6 páginas con tipos, condicionales, bucles, estructuras de datos, funciones y los errores típicos. Para tener al lado mientras programas. Gratis.

Sin spam. Email + cheatsheet + un correo por semana con tutoriales nuevos.

Tu siguiente paso

Si has llegado hasta aquí, ya tienes herramientas para escribir código mucho más limpio con diccionarios. La próxima vez que veas un if clave in d: con tres líneas para inicializar una lista — recuerda setdefault o defaultdict. La próxima vez que cuentes a mano — recuerda Counter.

Si quieres aprender estructuras de datos, funciones, clases y proyectos reales con Python desde la base, en El Pythonista lo enseño paso a paso.

Un abrazo,
Oscar

¿Quieres aprender Python en orden, no a saltos?

Esto que has leído es solo una pieza. En El Pythonista lo verás todo encadenado: 11 módulos, 35+ lecciones, código revisado, ejercicios y un proyecto real (MovieTracker) que crece contigo desde la primera variable hasta el deploy a producción.

Ver el curso completo →

35+ lecciones · Proyecto real · Acceso de por vida · 14 días de garantía

Compartir

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Publicar un comentario