Anidación de estructuras
En el mundo real los datos no vienen planos: vienen como listas dentro de listas, diccionarios dentro de diccionarios, listas de diccionarios con listas adentro. Esta lección te enseña a construir, navegar y transformar cualquier estructura anidada — la habilidad que necesitás para trabajar con JSON y pandas.
Concepto teórico
¿Qué es la anidación?
Anidar significa poner una estructura de datos dentro de otra. Python te permite combinar listas, tuplas, diccionarios y sets en cualquier profundidad. Los cuatro patrones de anidación que vas a usar constantemente son:
- Lista de listas — una matriz o tabla:
[[1,2],[3,4],[5,6]] - Lista de diccionarios — registros/filas de una tabla:
[{"nombre": "García", "score": 720}, ...] - Diccionario de diccionarios — datos jerárquicos / JSON:
{"cliente": {"nombre": "García", "scoring": {"valor": 720}}} - Diccionario de listas — columnas de una tabla:
{"nombre": ["García","López"], "score": [720,680]}
pd.DataFrame(data), data puede ser
cualquiera de estos 4 patrones. Y cuando consumís una API REST, la respuesta JSON es siempre una combinación de
patrones 2 y 3. Dominar anidación = dominar el formato de TODOS tus datos.Lista de listas — la "matriz"
Una lista de listas representa una tabla bidimensional, como una hoja de cálculo. Cada sublista es una "fila":
# Cada fila: [nombre, edad, score, saldo]
tabla = [
["García", 35, 720, 150000],
["López", 42, 680, 320000],
["Martínez", 28, 590, 45000],
]
# Acceso: tabla[fila][columna]
print(tabla[0][0]) # "García" (fila 0, columna 0)
print(tabla[1][3]) # 320000 (fila 1, columna 3)
print(tabla[2][2]) # 590 (fila 2, columna 2)
El problema de las listas de listas es que tenés que recordar qué posición es cada campo.
tabla[1][3] no dice nada — ¿es el saldo? ¿la edad? Por eso, para datos con campos nombrados, se
prefiere la lista de diccionarios.
Lista de diccionarios — la "base de datos en memoria"
Este es el patrón más importante de todo el curso. Cada diccionario es un registro (fila) con campos nombrados (columnas):
clientes = [
{"nombre": "García", "ciudad": "BsAs", "score": 720, "saldo": 150000},
{"nombre": "López", "ciudad": "Córdoba", "score": 680, "saldo": 320000},
{"nombre": "Martínez", "ciudad": "Rosario", "score": 590, "saldo": 45000},
]
# Acceso claro y descriptivo:
print(clientes[0]["nombre"]) # "García"
print(clientes[1]["saldo"]) # 320000
pd.DataFrame(clientes), pandas la convierte en una tabla perfecta automáticamente. Y cuando hagas
df.to_dict("records"), obtenés de vuelta esta misma estructura.
Diccionario de diccionarios — datos jerárquicos (JSON)
Cuando los datos tienen estructura jerárquica (un cliente tiene scoring, el scoring tiene subcampos), usás diccionarios dentro de diccionarios:
cliente = {
"id": 12345,
"nombre": "García",
"scoring": {
"valor": 720,
"fecha": "2025-01-15",
"entidad": "BCRA"
},
"cuentas": [
{"tipo": "CA$", "saldo": 150000},
{"tipo": "CA USD", "saldo": 5000}
]
}
# Acceso encadenado:
print(cliente["scoring"]["valor"]) # 720
print(cliente["cuentas"][0]["saldo"]) # 150000
KeyError. Para acceso seguro, usá .get() encadenado:
cliente.get("scoring", {}).get("valor", 0). Si "scoring" no existe, el {} evita que el
segundo .get() falle.
Diccionario de listas — formato columnar
Cada clave es una columna y su valor es la lista de datos de esa columna. Este es el formato que pandas usa internamente:
datos_columnar = {
"nombre": ["García", "López", "Martínez"],
"score": [720, 680, 590],
"saldo": [150000, 320000, 45000],
}
# pd.DataFrame(datos_columnar) → tabla perfecta
Patrones de recorrido profundo
Para recorrer estructuras anidadas necesitás for anidados. La regla es simple: un for por cada nivel de anidación:
- Lista simple: 1 for
- Lista de listas: 2 for
- Lista de dicts: 1 for + acceso por clave
- Dict de dicts: 1 for (sobre
.items()) + acceso a subniveles
.get() encadenado,
list comprehensions sobre sublistas, y extracciones selectivas es una habilidad que usás todos los días como
analista.Ejemplos explicados paso a paso
Ejemplo 1: Lista de listas — operaciones sobre tabla
Hacé clic en ▶ Ejecutar
Ejemplo 2: Lista de diccionarios — la estructura estrella
Hacé clic en ▶ Ejecutar
Ejemplo 3: Diccionario anidado — navegando JSON
Hacé clic en ▶ Ejecutar
Ejemplo 4: Construir estructura anidada desde datos planos
Hacé clic en ▶ Ejecutar
Ejemplo 5: Comprehensions sobre estructuras anidadas
Hacé clic en ▶ Ejecutar
Referencia rápida
| Patrón | Estructura | Acceso | Uso principal |
|---|---|---|---|
| Lista de listas | [[1,2],[3,4]] |
m[fila][col] |
Matrices, tablas sin encabezado |
| Lista de dicts | [{"k":v}, ...] |
lista[i]["clave"] |
Registros/filas de tabla (el más usado) |
| Dict de dicts | {"a": {"b": v}} |
d["a"]["b"] |
JSON, datos jerárquicos |
| Dict de listas | {"col": [v1,v2]} |
d["col"][i] |
Formato columnar (pandas interno) |
| Operación | Sintaxis |
|---|---|
| Extraer columna de lista de dicts | [d["campo"] for d in lista] |
| Filtrar registros | [d for d in lista if d["campo"] > x] |
| Aplanar lista de listas | [x for sub in lista for x in sub] |
| Aplanar sublistas de dicts | [item for d in lista for item in d["sublista"]] |
| Acceso seguro profundo | d.get("a", {}).get("b", default) |
| Convertir a DataFrame | pd.DataFrame(lista_de_dicts) |
Ejercicios
Ejercicio 1: Acceso a lista de listas
Dada tabla = [["GGAL",5200],["YPF",28000],["PAMP",3100]], imprimí el nombre y precio de cada
acción. Debe incluir 28000.
Hacé clic en ▶ Ejecutar
Ejercicio 2: Acceso a lista de dicts
Dada clientes = [{"nombre":"García","score":720},{"nombre":"López","score":680}], imprimí cada
nombre con su score. Debe incluir García.
Hacé clic en ▶ Ejecutar
Ejercicio 3: Acceso a dict anidado
Dado data = {"cliente": {"nombre": "Pérez", "scoring": {"valor": 810}}}, imprimí el nombre y el
valor del scoring accediendo con claves encadenadas. Debe incluir 810.
Hacé clic en ▶ Ejecutar
Ejercicio 4: Extraer columna de lista de dicts
De la lista de clientes, extraé todos los saldos en una lista usando comprehension. Calculá el total. Debe
incluir 1477000.
Hacé clic en ▶ Ejecutar
Ejercicio 5: Filtrar lista de dicts con comprehension
De la misma lista, filtrá los clientes con saldo > $100K e imprimí sus nombres. Debe incluir
Pérez.
Hacé clic en ▶ Ejecutar
Ejercicio 6: Aplanar lista de listas
Dada cuentas = [[150000, 500000], [320000], [890000, 5000, 12000]], aplanalas en una sola lista
y calculá el total. Debe incluir 1877000.
Hacé clic en ▶ Ejecutar
Ejercicio 7: Acceso seguro con .get() encadenado
Dado un dict donde algunos campos pueden no existir, accedé de forma segura al scoring, email y teléfono con
defaults. Debe incluir No informado.
Hacé clic en ▶ Ejecutar
Ejercicio 8: Construir lista de dicts desde datos planos
Dados nombres = ["García","López","Pérez"], scores = [720,680,810],
saldos = [150000,320000,890000], construí una lista de diccionarios con campos nombre, score,
saldo. Debe incluir 810.
Hacé clic en ▶ Ejecutar
Ejercicio 9: Comprehension sobre sublistas de dicts
Dados clientes con sublista de cuentas, extraé TODAS las cuentas como tuplas (nombre_cliente, tipo_cuenta,
saldo) con una comprehension anidada. Debe incluir CA$.
Hacé clic en ▶ Ejecutar
Ejercicio 10: Reporte completo desde API simulada
Procesá esta respuesta de API simulada: extraé el nombre del cliente, su score, listá todas las cuentas con
su saldo, calculá el saldo total, y verificá si el uso de tarjeta supera el 80% del límite. Debe incluir
REPORTE.
Hacé clic en ▶ Ejecutar
Resumen y conexión
- Los 4 patrones de anidación son: lista de listas (matriz), lista de dicts (tabla), dict de dicts (JSON), dict de listas (columnar).
- La lista de diccionarios es el patrón más importante — es la "base de datos en memoria" y el input
directo de
pd.DataFrame(). - Acceso profundo: encadená
[]o usá.get()encadenado para seguridad. - Comprehensions anidadas (
[x for sub in lista for x in sub]) aplanan y extraen datos de estructuras complejas. - Construir estructuras anidadas desde datos planos es un patrón fundamental para preparar datos.
En la siguiente lección (16 · While) vas a aprender el primer bucle con condición: cómo repetir código mientras se cumpla una condición, simulaciones financieras mes a mes, y patrones de validación de input.
Recursos: Nested List Comprehensions · JSON module