15 · Dicts: la estructura de datos más usada en Python
Búsquedas clave→valor, iteración con .items(), Counter, defaultdict y comprensiones de dict — todo lo que tocas en un proyecto real de ML.
Un dict mapea **claves** arbitrarias a **valores** con búsqueda O(1) — es el registro, configuración y caché universal de Python.
Sin esto:
Sin dicts, las configuraciones de hiperparámetros son tuplas posicionales propensas a errores de índice, las codificaciones de etiquetas requieren un escaneo de lista paralela y agrupar muestras por categoría necesita una pasada de ordenar y luego cortar.
Un literal de dict es {clave: valor, ...}. Las claves deben ser hasheables (strings, ints, tuplas); los valores pueden ser cualquier cosa. Lee un valor con d[clave] (lanza KeyError si no existe) o el más seguro d.get(clave, default) (devuelve default en lugar de lanzar). Comprueba la existencia con clave in d. Desde Python 3.7 los dicts preservan el orden de inserción — el orden en que agregaste las claves es el orden en que iteras.
Python (in browser)
`.get(clave, default)` es casi siempre preferible a `d[clave]` cuando la clave podría estar ausente — evita un `KeyError` sin necesitar una comprobación `if` explícita.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
En `{**defaults, **overrides}`, las claves de `overrides` sobrescriben las claves coincidentes de `defaults` — gana el lado derecho. Este es el patrón canónico para fusionar configuraciones.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
`Counter` es una subclase de dict — todos los métodos de Counter funcionan también en un dict plano, pero `most_common(n)` y la aritmética entre contadores son bonificaciones exclusivas.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
`defaultdict(list)` crea una lista vacía automáticamente la primera vez que se accede a una nueva clave — sin el repetitivo `if key not in d: d[key] = []`.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Dados `a = {'x': 1, 'y': 2}` y `b = {'y': 99, 'z': 3}`, ¿qué es `{**a, **b}`?
Construye contadores de frecuencia, lógica groupby y un codificador de etiquetas en el Arena con tests del lado del servidor.
Un dict es la forma de Python de expresar una *función* en el sentido matemático — un mapeo de un dominio de claves a un codominio de valores. El capítulo 1 de MML formaliza las funciones y los mapeos; los dicts son su encarnación computacional.
- `d.get(clave, default)` es la búsqueda de clave segura — sin `KeyError`, sin comprobación `if` explícita. Usa `d[clave]` solo cuando estés seguro de que la clave existe.
- `Counter` cuenta frecuencias; `defaultdict` inicializa automáticamente las claves faltantes. Ambos son subclases de dict de `collections`.
- `{**a, **b}` fusiona dos dicts — las claves de `b` sobrescriben las claves coincidentes de `a`. Python 3.9+ también admite `a | b`.
Grids de hiperparámetros: `{'lr': 0.01, 'batch_size': 32, 'dropout': 0.3}` — todo script de entrenamiento empieza con uno. Codificación de etiquetas: `label_to_idx = {'cat': 0, 'dog': 1, 'bird': 2}` mapea etiquetas de string a índices de clase enteros para las funciones de pérdida. `sklearn` expone los parámetros aprendidos mediante `model.get_params()` y `model.coef_` envueltos en una interfaz similar a un dict. El `state_dict()` de PyTorch es literalmente un dict de tensores de parámetros.
Si lo quitas: Sin dicts, una configuración de hiperparámetros es una tupla posicional — intercambiar el orden de `lr` y `batch_size` produce silenciosamente un error. La codificación de etiquetas sin un dict requiere arreglos paralelos y búsquedas O(n) en tiempo de inferencia.