¿Qué es una estructura anidada y por qué aparece en datos reales?
En datos del mundo real, una sola estructura suele quedarse corta: una entidad tiene varios atributos (por ejemplo, un alumno tiene nombre, id y notas) y además existen relaciones (por ejemplo, una categoría agrupa productos). Una estructura anidada combina colecciones dentro de otras colecciones para reflejar esa realidad: listas de diccionarios (muchas entidades, cada una con atributos) y diccionarios de listas (una clave que agrupa múltiples elementos).
Regla práctica para elegir la forma
- Lista de diccionarios: cuando tienes una colección de “registros” similares (alumnos, productos, contactos) y recorres o filtras por condiciones.
- Diccionario de listas: cuando necesitas acceder rápido por una clave de agrupación (categoría, estado, etiqueta) y obtener todos los elementos asociados.
- Diccionario de diccionarios (variación útil): cuando necesitas acceso directo por id sin recorrer.
Diseño guiado por requisitos: qué consultas necesitas
Antes de escribir código, define las consultas típicas. La forma de los datos debe facilitar esas operaciones.
Checklist de consultas
- Por id: “dame el alumno con id=10”, “dame el producto SKU=ABC”.
- Por categoría: “dame productos de ‘lácteos’”.
- Por rango/condición: “alumnos con promedio > 8”, “productos con stock < 5”.
- Actualizaciones profundas: “cambiar el teléfono de un contacto”, “agregar una nota a un alumno”, “sumar un producto al carrito”.
Cómo las consultas determinan la estructura
| Consulta principal | Estructura recomendada | Motivo |
|---|---|---|
| Acceso frecuente por id | diccionario[id] -> registro | Evita recorrer; acceso directo |
| Listado/filtrado por condición | lista de registros | Recorrer y filtrar es natural |
| Agrupar por categoría | diccionario[categoria] -> lista | Obtienes el grupo completo por clave |
| Necesitas ambas (por id y por categoría) | Estructuras paralelas o índice adicional | Optimiza dos rutas de acceso |
Lista de diccionarios: alumnos con nombre y notas
Modelo base
Representa cada alumno como un diccionario con atributos. La colección completa es una lista.
alumnos = [ {"id": 1, "nombre": "Ana", "notas": [9, 8, 10]}, {"id": 2, "nombre": "Luis", "notas": [7, 6]}, {"id": 3, "nombre": "Mara", "notas": []}]Diagrama de datos (cajas y flechas)
alumnos (lista) ├── [0] ──> { id: 1, nombre: "Ana", notas: [9, 8, 10] } ├── [1] ──> { id: 2, nombre: "Luis", notas: [7, 6] } └── [2] ──> { id: 3, nombre: "Mara", notas: [] }Este tipo de diagrama ayuda a no confundir índices (posición en la lista) con claves (campos del diccionario) y con sublistas (notas).
Acceso en profundidad (leer datos)
- Nombre del primer alumno:
alumnos[0]["nombre"] - Segunda nota de Ana:
alumnos[0]["notas"][1] - Lista de notas de Luis:
alumnos[1]["notas"]
Actualización en profundidad (editar y agregar)
Editar un campo (cambiar el nombre del alumno id=2). Como la estructura es una lista, normalmente primero lo encuentras recorriendo:
- Escuche el audio con la pantalla apagada.
- Obtenga un certificado al finalizar.
- ¡Más de 5000 cursos para que explores!
Descargar la aplicación
objetivo_id = 2for alumno in alumnos: if alumno["id"] == objetivo_id: alumno["nombre"] = "Luis Alberto" breakAgregar un elemento a una lista dentro de un diccionario (agregar una nota a Mara):
for alumno in alumnos: if alumno["nombre"] == "Mara": alumno["notas"].append(9) breakConsulta por rango/condición: promedio mayor a 8
Para condiciones, suele ser natural recorrer y filtrar. Si un alumno no tiene notas, decide una regla (por ejemplo, excluirlo).
destacados = []for alumno in alumnos: notas = alumno["notas"] if len(notas) == 0: continue promedio = sum(notas) / len(notas) if promedio > 8: destacados.append(alumno["nombre"])Mejora cuando “por id” es muy frecuente: índice por id
Si constantemente buscas por id, puedes construir un diccionario auxiliar (un “índice”) para acceso directo, manteniendo la lista para recorridos.
indice_alumnos = {}for alumno in alumnos: indice_alumnos[alumno["id"]] = alumno# Acceso directoalumno_2 = indice_alumnos[2]alumno_2["notas"].append(10)Idea clave: el índice apunta al mismo diccionario del alumno, así que actualizar por el índice actualiza el registro original.
Diccionario de listas: categoría → productos
Modelo base
Cuando la consulta típica es “dame todos los productos de una categoría”, un diccionario donde cada clave es la categoría y el valor es una lista de productos funciona muy bien.
catalogo = { "frutas": [ {"sku": "F01", "nombre": "Manzana", "precio": 1.2}, {"sku": "F02", "nombre": "Banana", "precio": 0.9} ], "lacteos": [ {"sku": "L01", "nombre": "Leche", "precio": 1.5} ], "panaderia": []}Diagrama de datos (cajas y flechas)
catalogo (diccionario) ├── "frutas" ──> [ {sku: F01, ...}, {sku: F02, ...} ] ├── "lacteos" ──> [ {sku: L01, ...} ] └── "panaderia" ──> [ ]Acceso en profundidad
- Todos los productos de frutas:
catalogo["frutas"] - Nombre del primer producto de lácteos:
catalogo["lacteos"][0]["nombre"] - Precio de la banana (recorriendo la lista de la categoría):
precio_banana = Nonefor producto in catalogo["frutas"]: if producto["sku"] == "F02": precio_banana = producto["precio"] breakActualización en profundidad: editar un campo dentro de un producto
Ejemplo: cambiar el precio de “Leche” en la categoría “lacteos”.
for producto in catalogo["lacteos"]: if producto["sku"] == "L01": producto["precio"] = 1.6 breakAgregar un producto a una categoría (lista dentro del diccionario)
nuevo = {"sku": "P10", "nombre": "Pan integral", "precio": 2.3}catalogo["panaderia"].append(nuevo)Si la categoría podría no existir, define una estrategia: crearla al vuelo.
categoria = "bebidas"producto = {"sku": "B01", "nombre": "Agua", "precio": 0.7}if categoria not in catalogo: catalogo[categoria] = []catalogo[categoria].append(producto)Guía paso a paso para diseñar tu estructura anidada
Paso 1: lista las entidades y sus atributos
Ejemplo “alumnos”: atributos: id, nombre, notas. Ejemplo “producto”: sku, nombre, precio, stock.
Paso 2: define relaciones y agrupaciones
Ejemplo “productos por categoría”: una categoría agrupa muchos productos.
Paso 3: escribe 3–5 consultas reales que tu programa debe responder
- “Buscar alumno por id”
- “Agregar nota a un alumno”
- “Listar productos de una categoría”
- “Encontrar productos con precio en un rango”
Paso 4: elige la forma mínima que haga fáciles esas consultas
- Si “por id” manda: diccionario por id.
- Si “por categoría” manda: diccionario de listas.
- Si necesitas filtrar por condiciones variadas: lista de registros (y opcionalmente índices auxiliares).
Paso 5: dibuja el diagrama de niveles
Haz un esquema tipo “cajas y flechas” y marca qué es lista y qué es diccionario en cada nivel. Esto reduce errores como intentar usar una clave en una lista o un índice en un diccionario.
Ejercicios realistas (lectura y escritura)
1) Carrito de compras (lista de diccionarios + diccionario de totales)
Datos:
carrito = [ {"sku": "F01", "nombre": "Manzana", "precio": 1.2, "cantidad": 3}, {"sku": "L01", "nombre": "Leche", "precio": 1.5, "cantidad": 2}]Ejercicio A (lectura): calcula el total a pagar (precio * cantidad) recorriendo la lista.
Ejercicio B (escritura): aumenta en 1 la cantidad del producto con sku="L01".
Ejercicio C (escritura profunda): agrega un campo "descuento" al producto “Manzana” y asígnale 0.1 (10%).
2) Inventario por categoría (diccionario de listas + actualización de stock)
Datos:
inventario = { "frutas": [ {"sku": "F01", "stock": 10}, {"sku": "F02", "stock": 5} ], "lacteos": [ {"sku": "L01", "stock": 2} ]}Ejercicio A (lectura): lista todos los SKU de “frutas”.
Ejercicio B (escritura profunda): reduce en 1 el stock de sku="L01" dentro de “lacteos”.
Ejercicio C (consulta por rango): encuentra todos los productos con stock <= 2 (recorriendo todas las categorías).
3) Agenda de contactos (lista de diccionarios con listas internas)
Datos:
contactos = [ {"id": 1, "nombre": "Sofía", "telefonos": ["555-0101"], "emails": ["sofia@mail.com"]}, {"id": 2, "nombre": "Diego", "telefonos": [], "emails": []}]Ejercicio A (lectura): muestra el primer email de Sofía (si existe).
Ejercicio B (escritura profunda): agrega un teléfono a Diego.
Ejercicio C (edición de campo): cambia el nombre del contacto con id=1 a “Sofía R.”.
4) Reto de diseño: ¿una estructura o dos?
Requisito: “Buscar producto por sku” y también “Listar productos por categoría”.
- Pregunta: ¿usarías solo
catalogo[categoria] -> listao además unindice_sku[sku] -> producto? - Ejercicio: dibuja dos diagramas (uno con una sola estructura y otro con índice adicional) y escribe qué operación se vuelve más simple en cada caso.