Diccionarios
Las listas te permiten buscar cosas por posición. Pero a menudo querés buscar algo por nombre. No "dame el elemento 3", sino "dame el puntaje de Sofía". Un diccionario almacena datos como pares clave-valor: buscás un valor por su clave, no por su posición.
Crear un diccionario
Llaves con dos puntos entre cada clave y valor, y comas entre los pares. Las claves son casi siempre cadenas. Los valores pueden ser cualquier cosa: números, cadenas, otras listas, incluso otros diccionarios.
player = {
"name": "Sofía",
"score": 87,
"level": 5,
"alive": True,
}Acceder a los valores
Usá corchetes con la clave para obtener el valor. Si la clave no existe, Python lanza un KeyError. Usá .get() cuando no estés seguro de que una clave esté: devuelve None en lugar de fallar, o un valor por defecto que especifiques.
player = {"name": "Sofía", "score": 87}
player["name"] # "Sofía"
player["score"] # 87
player["lives"] # KeyError (key doesn't exist)player.get("score") # 87
player.get("lives") # None (no error, returns None by default)
player.get("lives", 3) # 3 (use this default if key is absent).get() es más seguro siempre que una clave pueda faltar:
count = inventory.get("arrows", 0) # 0 if "arrows" isn't in the dictAgregar y actualizar
Asigná a una clave con corchetes. Si la clave ya existe, el valor se reemplaza. Si todavía no existe, se crea una nueva entrada. Usá .update() para combinar otro diccionario entero de una sola vez.
player = {"name": "Sofía", "score": 87}
player["score"] = 92 # update existing
player["level"] = 5 # add new keyextras = {"level": 5, "alive": True}
player.update(extras) # adds/overwrites with keys from extrasEliminar elementos
Cuatro formas de eliminar entradas. .pop() elimina una clave y te devuelve el valor. .pop() con un valor por defecto es seguro cuando la clave podría no estar. del elimina una clave sin valor de retorno. .clear() vacía todo el diccionario.
player = {"name": "Sofía", "score": 87, "level": 5}
player.pop("level") # removes "level" and returns 5
player.pop("lives", None) # safe pop, returns None if key absent
del player["score"] # removes "score", no return value
player.clear() # removes everything.pop() con un valor por defecto es la forma más segura de eliminar una clave que podría no existir.
Iterar
Tres vistas te permiten recorrer diferentes partes de un diccionario. Iterar solo el diccionario te da las claves. .values() da los valores. .items() da ambos a la vez y es lo que más vas a usar: desempaquetá cada par en dos nombres para bucles limpios y legibles.
player = {"name": "Sofía", "score": 87, "level": 5}
for key in player: # iterate keys (most common)
print(key)
for key in player.keys(): # same, explicit keys view
print(key)
for value in player.values(): # just the values
print(value)
for key, value in player.items(): # both, most useful
print(f"{key}: {value}").items() es lo que más vas a usar. Desempaquetar cada par en dos nombres hace que el bucle sea legible.
Verificar pertenencia
in verifica si una clave existe en el diccionario. No verifica los valores, solo las claves. Para verificar si algo no está presente, usá not in.
player = {"name": "Sofía", "score": 87}
"name" in player # True
"lives" in player # False
"lives" not in player # Truein solo verifica las claves. Para verificar valores, usá in player.values(), aunque eso rara vez se necesita.
Diccionarios anidados
Los valores pueden ser diccionarios en sí mismos. Así es como representás datos estructurados con múltiples niveles: un jugador que tiene una sección de estadísticas, un archivo de configuración con subsecciones. Dos pares de corchetes acceden a un valor anidado: el primero elige la clave externa, el segundo elige la clave interna.
users = {
"sofia": {"score": 87, "level": 5},
"mateo": {"score": 74, "level": 3},
}
users["sofia"]["score"] # 87
users["mateo"]["level"] # 3Se accede con corchetes encadenados. Para estructuras profundamente anidadas, esto puede volverse poco manejable, así que mantené el anidamiento poco profundo donde puedas.
setdefault
.setdefault() lee una clave si existe, o la establece a un valor por defecto si no, y luego devuelve el valor. Es útil cuando necesitás que una clave exista pero no querés sobrescribirla si ya está ahí.
inventory = {}
inventory.setdefault("arrows", 0) # sets "arrows": 0, returns 0
inventory.setdefault("arrows", 10) # "arrows" already exists, no change, returns 0Es útil para construir estructuras agrupadas sin verificar primero la existencia de la clave:
groups = {}
for name, team in players:
groups.setdefault(team, []).append(name)collections.defaultdict y Counter
La biblioteca estándar tiene dos subclases de diccionario que manejan automáticamente patrones comunes. defaultdict crea un valor por defecto para las claves faltantes para que nunca tengas un KeyError. Counter cuenta con qué frecuencia aparece cada elemento en una secuencia y te da los resultados como un diccionario.
importación de collections
defaultdict y Counter necesitan importarse desde la biblioteca estándar. Las importaciones se cubren en el capítulo Modules.
from collections import defaultdict
groups = defaultdict(list)
for name, team in players:
groups[team].append(name) # no KeyError if team is newfrom collections import Counter
words = ["cat", "dog", "cat", "bird", "cat", "dog"]
counts = Counter(words)
# Counter({'cat': 3, 'dog': 2, 'bird': 1})
counts.most_common(2) # [('cat', 3), ('dog', 2)]Counter ahorra un montón de código repetitivo de "contar cosas en un bucle".
En la práctica
Construir un registro de puntajes e imprimir un resumen con todas las entradas:
scores = {"Sofía": 87, "Mateo": 74, "Camila": 92, "Diego": 55}
total = sum(scores.values())
average = total / len(scores)
print(f"Players: {len(scores)}")
print(f"Average: {average:.1f}")
print(f"Highest: {max(scores.values())}")
print(f"Lowest: {min(scores.values())}")
print()
for name, score in scores.items():
print(f" {name}: {score}")
