🗂️ Diccionarios

Los diccionarios son perfectos para problemas de conteo, agrupación y búsqueda rápida. Aparecen en casi todos los problemas de nivel medio.

📦 Conceptos básicos

📖 Del libro

Un diccionario es una colección de pares clave-valor. Usas la clave para acceder al valor, como buscar una palabra en un diccionario real. Se crean con llaves {}.

→ Python Crash Course, Capítulo 6, pp. 91-97

# Crear diccionario
persona = {
    "nombre": "Ana",
    "edad": 25,
    "ciudad": "Madrid"
}

# Acceder a valores
persona["nombre"]      # 'Ana'
persona["edad"]        # 25

# Añadir/modificar
persona["email"] = "ana@mail.com"
persona["edad"] = 26

# Eliminar
del persona["ciudad"]

🔑 Métodos esenciales

d = {"a": 1, "b": 2, "c": 3}

# Comprobar si existe clave
"a" in d          # True
"z" in d          # False

# get() - devuelve valor o default si no existe
d.get("a")         # 1
d.get("z")         # None
d.get("z", 0)      # 0 (valor por defecto)

# Obtener claves, valores, pares
d.keys()          # ['a', 'b', 'c']
d.values()        # [1, 2, 3]
d.items()         # [('a', 1), ('b', 2), ('c', 3)]

🔁 Recorrer diccionarios

📖 Del libro

Puedes recorrer solo las claves, solo los valores, o ambos a la vez con items().

→ Python Crash Course, Capítulo 6, pp. 99-103

d = {"Ana": 20, "Luis": 25, "Eva": 22}

# Solo claves
for nombre in d:
    print(nombre)

# Clave y valor
for nombre, edad in d.items():
    print(f"{nombre} tiene {edad}")

⭐ EL PATRÓN MÁS IMPORTANTE: Contar frecuencias

🛑
Memoriza esto: Aparece en el 30% de problemas de CodeWars.
# Contar letras en un texto
texto = input()
frecuencias = {}

for letra in texto:
    frecuencias[letra] = frecuencias.get(letra, 0) + 1

# Ejemplo: "banana"
# frecuencias = {'b': 1, 'a': 3, 'n': 2}
💡
El truco del get():
d.get(clave, 0) + 1
Si la clave no existe, usa 0 y suma 1. Si existe, suma 1 al valor actual.

Variantes del patrón de conteo

# Contar palabras
texto = input()
palabras = texto.split()
conteo = {}
for p in palabras:
    conteo[p] = conteo.get(p, 0) + 1

# Agrupar por criterio
# Ej: agrupar nombres por inicial
nombres = ["Ana", "Alberto", "Luis", "Laura"]
grupos = {}
for n in nombres:
    inicial = n[0]
    if inicial not in grupos:
        grupos[inicial] = []
    grupos[inicial].append(n)
# {'A': ['Ana', 'Alberto'], 'L': ['Luis', 'Laura']}

🎯 Patrones comunes en CodeWars

1. Encontrar el elemento más frecuente

texto = input()
frecuencias = {}
for c in texto:
    frecuencias[c] = frecuencias.get(c, 0) + 1

# Encontrar máximo
mas_comun = max(frecuencias, key=frecuencias.get)
print(mas_comun, frecuencias[mas_comun])

2. Ordenar por valor del diccionario

puntos = {"Ana": 85, "Luis": 92, "Eva": 78}

# Ordenar por puntuación (descendente)
ranking = sorted(puntos.items(), key=lambda x: x[1], reverse=True)
# [('Luis', 92), ('Ana', 85), ('Eva', 78)]

for nombre, pts in ranking:
    print(f"{nombre}: {pts}")

3. Invertir diccionario (valor → clave)

original = {"a": 1, "b": 2, "c": 3}
invertido = {v: k for k, v in original.items()}
# {1: 'a', 2: 'b', 3: 'c'}

4. Problema tipo: Medallero olímpico

# Entrada: país oro plata bronce por línea
# Ordenar por oro, luego plata, luego bronce

n = int(input())
paises = {}

for _ in range(n):
    partes = input().split()
    pais = partes[0]
    oro, plata, bronce = int(partes[1]), int(partes[2]), int(partes[3])
    paises[pais] = (oro, plata, bronce)

# Ordenar por medallas (oro primero, luego plata, luego bronce)
ranking = sorted(paises.items(), 
                 key=lambda x: (-x[1][0], -x[1][1], -x[1][2]))

for pais, medallas in ranking:
    print(pais, medallas[0], medallas[1], medallas[2])

✅ Ejercicios de práctica

📝
Ejercicio: Lee un texto y muestra qué letra aparece más veces.
👁️ Ver solución
texto = input().lower()
freq = {}
for c in texto:
    if c.isalpha():
        freq[c] = freq.get(c, 0) + 1

mas_comun = max(freq, key=freq.get)
print(f"{mas_comun}: {freq[mas_comun]}")