Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Diccionarios: El Sistema de Inventario Inteligente

🧭 Navegación:

¡Bienvenido al sistema de inventario inteligente de nuestro almacén! En este capítulo, aprenderás sobre los diccionarios, una estructura de datos extremadamente poderosa y versátil en Python.

🏷️ El sistema de inventario con etiquetas inteligentes

Imagina que acabas de implementar un sistema de inventario ultra moderno en tu almacén. Este sistema tiene características especiales:

  • Cada producto tiene un código único (como un código de barras o QR)
  • Puedes encontrar cualquier producto instantáneamente solo con su código
  • No importa cuántos productos tengas - la búsqueda siempre es igual de rápida
  • Cada código está asociado a toda la información del producto
  • Nunca hay códigos duplicados - cada uno es único

En Python, los diccionarios funcionan exactamente así: son colecciones de pares clave-valor donde cada clave es única y te permite acceder instantáneamente a su valor asociado.

# Tu sistema de inventario inteligente en acción
inventario = {
    "LAP001": {"nombre": "Laptop Dell", "precio": 800, "stock": 5},
    "MOU001": {"nombre": "Mouse Logitech", "precio": 25, "stock": 20},
    "TEC001": {"nombre": "Teclado Mecánico", "precio": 60, "stock": 15}
}

print("🏷️ Sistema de inventario inteligente:")
codigo = "LAP001"
producto = inventario[codigo]
print(f"Código {codigo}: {producto['nombre']}")
print(f"Precio: ${producto['precio']}")
print(f"Stock: {producto['stock']} unidades")

# ¡Búsqueda instantánea sin importar el tamaño del inventario!

🔍 Mi perspectiva: Cuando empecé a programar, me costaba entender la diferencia entre listas y diccionarios. Todo cambió cuando me di cuenta de que las listas son como buscar productos recorriendo cada estante, mientras que los diccionarios son como usar un escáner de código de barras: ¡instantáneo! Esta analogía transformó mi forma de estructurar datos.

Características principales de los diccionarios

1. ✅ Pares clave-valor: Cada elemento tiene una etiqueta única

Los diccionarios almacenan información en pares clave-valor, donde la clave es como el código de barras y el valor es toda la información asociada:

empleado = {
    "id": "E12345",             # clave: "id", valor: "E12345"
    "nombre": "Ana García",     # clave: "nombre", valor: "Ana García"
    "edad": 28,                 # clave: "edad", valor: 28
    "puesto": "Gerente",        # clave: "puesto", valor: "Gerente"
    "salario": 75000            # clave: "salario", valor: 75000
}

print(f"Empleado: {empleado['nombre']}")
print(f"Puesto: {empleado['puesto']}")

2. ✅ Ordenados por inserción (Python ≥ 3.7): Mantienen el orden

A partir de Python 3.7, los diccionarios mantienen el orden en que se agregaron los elementos:

proceso_pedido = {
    "recibir": "Pedido recibido",
    "verificar": "Stock verificado", 
    "procesar": "Pedido procesado",
    "enviar": "Pedido enviado"
}

print("Pasos del proceso:")
for paso, estado in proceso_pedido.items():
    print(f"- {paso}: {estado}")

# Se imprime en el mismo orden en que se definieron

3. ✅ Modificables (Mutables): Puedes actualizar la información

Puedes añadir, cambiar o eliminar información en cualquier momento:

producto = {"nombre": "Laptop", "precio": 800}

# Actualizar el precio
producto["precio"] = 750

# Añadir información nueva
producto["descuento"] = 0.1
producto["stock"] = 5

# Eliminar información
del producto["descuento"]

print(f"Producto actualizado: {producto}")

4. ✅ Claves únicas: No puede haber códigos duplicados

Si intentas usar la misma clave dos veces, la segunda sobrescribe a la primera:

config = {
    "host": "localhost",
    "puerto": 8080,
    "host": "servidor.com"  # Esta sobrescribe la anterior
}
print(config)  # {'host': 'servidor.com', 'puerto': 8080}

5. ✅ Acceso súper rápido: Búsqueda instantánea

La búsqueda por clave es O(1) - tiempo constante, sin importar el tamaño del diccionario:

# Igual de rápido con 10 elementos o 10,000,000
gran_inventario = {f"PROD{i}": f"Producto {i}" for i in range(1000000)}
producto = gran_inventario["PROD500000"]  # ¡Instantáneo!
print(f"Producto encontrado: {producto}")

Creando tu propio sistema de inventario (diccionarios)

Hay varias formas de crear diccionarios en Python:

Método 1: Diccionario vacío listo para llenar

# Diccionario completamente vacío
inventario = {}
tambien_vacio = dict()  # Otra forma de crear un diccionario vacío

Método 2: Diccionario con elementos iniciales

# Diccionario ya con productos
stock = {
    "laptop": 15,
    "mouse": 50,
    "teclado": 30,
    "monitor": 8
}

Método 3: Diccionario usando dict() con argumentos nombrados

# Crear diccionario con argumentos nombrados
empleado = dict(nombre="Ana", edad=28, departamento="Ventas")
print(empleado)  # {'nombre': 'Ana', 'edad': 28, 'departamento': 'Ventas'}

Método 4: Diccionario a partir de pares clave-valor

# Crear diccionario a partir de lista de tuplas (clave, valor)
datos = [("nombre", "Carlos"), ("edad", 35), ("ciudad", "Madrid")]
persona = dict(datos)
print(persona)  # {'nombre': 'Carlos', 'edad': 35, 'ciudad': 'Madrid'}

Método 5: Diccionario por comprensión

# Generar diccionario con una fórmula
cuadrados = {x: x**2 for x in range(1, 6)}
print(cuadrados)  # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

Método 6: Diccionario con zip()

# Combinar dos listas en un diccionario
claves = ["nombre", "edad", "puesto"]
valores = ["María", 30, "Analista"]
empleado = dict(zip(claves, valores))
print(empleado)  # {'nombre': 'María', 'edad': 30, 'puesto': 'Analista'}

Operaciones básicas con diccionarios

1. Accediendo a la información

producto = {"nombre": "Laptop", "precio": 800, "stock": 5}

# Acceso directo (puede causar error si la clave no existe)
nombre = producto["nombre"]
print(f"Nombre: {nombre}")

# get() - acceso seguro con valor por defecto
precio = producto.get("precio", 0)  # 800
descuento = producto.get("descuento", 0)  # 0 (valor por defecto)
print(f"Precio: ${precio}, Descuento: {descuento}%")

# setdefault() - obtener o establecer valor por defecto
garantia = producto.setdefault("garantia", "1 año")  # Si no existe, la crea
print(f"Garantía: {garantia}")
print(producto)  # Ahora incluye 'garantia': '1 año'

🔍 Mi perspectiva: Siempre recomiendo usar get() en lugar de acceso directo con corchetes cuando no estás 100% seguro de que la clave existe. Me ha salvado de muchos errores en producción, especialmente cuando trabajo con datos que vienen de APIs externas.

2. Explorando el inventario

producto = {"nombre": "Laptop", "precio": 800, "stock": 5, "categoria": "Electrónicos"}

# keys() - obtener todas las claves
claves = producto.keys()
print(f"Información disponible: {list(claves)}")

# values() - obtener todos los valores
valores = producto.values()
print(f"Valores: {list(valores)}")

# items() - obtener pares clave-valor
pares = producto.items()
print(f"Pares clave-valor: {list(pares)}")

# Iteración sobre el diccionario
print("\nDetalles del producto:")
for clave, valor in producto.items():
    print(f"- {clave}: {valor}")

3. Actualizando el inventario

inventario = {"laptop": 10, "mouse": 25}

# Agregar/modificar elementos
inventario["teclado"] = 15      # Agregar nuevo
inventario["laptop"] = 12       # Modificar existente

# update() - actualizar con otro diccionario
nuevos_productos = {"monitor": 8, "webcam": 20}
inventario.update(nuevos_productos)

# update() con argumentos nombrados
inventario.update(altavoces=12, microfono=8)

print(f"Inventario actualizado: {inventario}")

4. Eliminando productos

inventario = {"laptop": 10, "mouse": 25, "teclado": 15, "monitor": 8, "webcam": 20}

# pop() - eliminar y devolver valor
stock_mouse = inventario.pop("mouse")
print(f"Stock de mouse eliminado: {stock_mouse}")
print(f"Inventario: {inventario}")

# pop() con valor por defecto (no genera error si la clave no existe)
stock_tablet = inventario.pop("tablet", 0)
print(f"Stock de tablet: {stock_tablet}")

# popitem() - eliminar y devolver último par (Python ≥ 3.7)
ultimo_item = inventario.popitem()
print(f"Último item eliminado: {ultimo_item}")

# del - eliminar por clave
del inventario["teclado"]
print(f"Después de eliminar teclado: {inventario}")

# clear() - vaciar completamente
inventario_temp = {"a": 1, "b": 2}
inventario_temp.clear()
print(f"Inventario vacío: {inventario_temp}")

Técnicas avanzadas para gestionar tu inventario

1. Diccionarios anidados: Información detallada y estructurada

Los diccionarios anidados te permiten organizar información compleja de manera jerárquica:

# Sistema de inventario con categorías y productos
inventario_completo = {
    "electrónicos": {
        "laptops": {
            "LAP001": {"nombre": "Laptop Dell XPS", "precio": 1200, "stock": 5},
            "LAP002": {"nombre": "MacBook Pro", "precio": 1800, "stock": 3}
        },
        "smartphones": {
            "CEL001": {"nombre": "iPhone 13", "precio": 999, "stock": 10},
            "CEL002": {"nombre": "Samsung S21", "precio": 850, "stock": 8}
        }
    },
    "muebles": {
        "sillas": {
            "SIL001": {"nombre": "Silla Ergonómica", "precio": 250, "stock": 15}
        },
        "mesas": {
            "MES001": {"nombre": "Mesa de Oficina", "precio": 350, "stock": 7}
        }
    }
}

# Acceder a información anidada
laptop_dell = inventario_completo["electrónicos"]["laptops"]["LAP001"]
print(f"Producto: {laptop_dell['nombre']}, Precio: ${laptop_dell['precio']}")

# Añadir nuevo producto a una categoría existente
inventario_completo["electrónicos"]["smartphones"]["CEL003"] = {
    "nombre": "Google Pixel", 
    "precio": 799, 
    "stock": 12
}

# Añadir nueva categoría
inventario_completo["accesorios"] = {
    "auriculares": {
        "AUR001": {"nombre": "Auriculares Bluetooth", "precio": 89, "stock": 20}
    }
}

2. Diccionarios por comprensión: Generación automática

Las comprensiones de diccionarios te permiten crear y transformar diccionarios de manera concisa:

# Crear diccionario de precios con IVA incluido
productos = {"laptop": 800, "mouse": 25, "teclado": 60, "monitor": 300}
productos_con_iva = {nombre: precio * 1.21 for nombre, precio in productos.items()}
print(f"Precios con IVA: {productos_con_iva}")

# Filtrar productos caros
productos_caros = {nombre: precio for nombre, precio in productos.items() if precio > 100}
print(f"Productos caros: {productos_caros}")

# Crear diccionario con formato específico
nombres = ["Ana", "Carlos", "María", "Pedro"]
ids_empleados = {nombre: f"EMP{i+1:03d}" for i, nombre in enumerate(nombres)}
print(f"IDs de empleados: {ids_empleados}")

3. Fusión y comparación de diccionarios

# Fusionar diccionarios (Python ≥ 3.9)
inventario_sede_a = {"laptop": 10, "mouse": 20, "teclado": 15}
inventario_sede_b = {"monitor": 8, "laptop": 5, "webcam": 12}

# Usando el operador | (Python 3.9+)
inventario_total = inventario_sede_a | inventario_sede_b
print(f"Inventario total: {inventario_total}")

# En versiones anteriores
from collections import ChainMap
inventario_combinado = dict(ChainMap(inventario_sede_b, inventario_sede_a))
print(f"Inventario combinado: {inventario_combinado}")

# Comparar diccionarios
config_predeterminada = {"tema": "claro", "notificaciones": True, "idioma": "es"}
config_usuario = {"tema": "oscuro", "idioma": "es"}

# Encontrar diferencias
diferencias = {k: config_usuario[k] for k in config_usuario 
               if k in config_predeterminada and config_usuario[k] != config_predeterminada[k]}
print(f"Configuraciones personalizadas: {diferencias}")

4. Copia de diccionarios: Superficial vs. Profunda

original = {"a": 1, "b": [2, 3, 4], "c": {"x": 10}}

# copy() - copia superficial
copia_superficial = original.copy()
copia_superficial["a"] = 999
copia_superficial["b"].append(5)  # ¡Modifica el original también!

print(f"Original después de modificar copia superficial: {original}")
# La lista en 'b' se modificó en ambos diccionarios

# deepcopy() - copia profunda
import copy
copia_profunda = copy.deepcopy(original)
copia_profunda["b"].append(6)  # No afecta el original

print(f"Original después de modificar copia profunda: {original}")
# La lista en 'b' no se modificó en el original

Aplicaciones prácticas de los diccionarios

1. Sistema de gestión de inventario

def gestionar_inventario():
    """Sistema simple de gestión de inventario usando diccionarios"""
    
    # Inventario inicial
    inventario = {
        "LAP001": {"nombre": "Laptop", "precio": 800, "stock": 5, "categoria": "Electrónicos"},
        "MOU001": {"nombre": "Mouse", "precio": 25, "stock": 10, "categoria": "Accesorios"},
        "TEC001": {"nombre": "Teclado", "precio": 60, "stock": 8, "categoria": "Accesorios"}
    }
    
    # Función para añadir producto
    def agregar_producto(codigo, nombre, precio, stock, categoria):
        if codigo in inventario:
            print(f"⚠️ El código {codigo} ya existe. Use otro código.")
            return False
        
        inventario[codigo] = {
            "nombre": nombre,
            "precio": precio,
            "stock": stock,
            "categoria": categoria
        }
        print(f"✅ Producto {codigo} ({nombre}) agregado correctamente.")
        return True
    
    # Función para actualizar stock
    def actualizar_stock(codigo, cantidad):
        if codigo not in inventario:
            print(f"❌ El código {codigo} no existe en el inventario.")
            return False
        
        inventario[codigo]["stock"] += cantidad
        print(f"✅ Stock de {inventario[codigo]['nombre']} actualizado a {inventario[codigo]['stock']} unidades.")
        return True
    
    # Función para mostrar inventario
    def mostrar_inventario():
        print("\n📦 INVENTARIO ACTUAL:")
        print("-" * 60)
        print(f"{'CÓDIGO':<10}{'PRODUCTO':<20}{'PRECIO':<10}{'STOCK':<10}{'CATEGORÍA':<15}")
        print("-" * 60)
        
        for codigo, datos in inventario.items():
            print(f"{codigo:<10}{datos['nombre']:<20}${datos['precio']:<9}{datos['stock']:<10}{datos['categoria']:<15}")
    
    # Función para buscar por categoría
    def buscar_por_categoria(categoria):
        productos = {codigo: datos for codigo, datos in inventario.items() 
                    if datos["categoria"].lower() == categoria.lower()}
        
        if not productos:
            print(f"❌ No hay productos en la categoría '{categoria}'.")
            return
        
        print(f"\n🔍 Productos en categoría '{categoria}':")
        for codigo, datos in productos.items():
            print(f"  • {datos['nombre']} (${datos['precio']}) - Stock: {datos['stock']}")
    
    # Demostración del sistema
    mostrar_inventario()
    
    # Agregar nuevo producto
    agregar_producto("MON001", "Monitor 24\"", 200, 3, "Electrónicos")
    
    # Actualizar stock
    actualizar_stock("MOU001", 5)  # Añadir 5 unidades
    actualizar_stock("TEC001", -2)  # Restar 2 unidades
    
    # Mostrar inventario actualizado
    mostrar_inventario()
    
    # Buscar por categoría
    buscar_por_categoria("Accesorios")

# Ejecutar el sistema
gestionar_inventario()

2. Análisis de datos de ventas

def analizar_ventas(datos_ventas):
    """Analiza datos de ventas agrupados por diferentes criterios"""
    
    # Inicializar diccionarios para análisis
    ventas_por_mes = {}
    ventas_por_producto = {}
    ventas_por_vendedor = {}
    
    # Procesar cada venta
    for venta in datos_ventas:
        fecha = venta["fecha"]
        mes = fecha[:7]  # "2024-01"
        producto = venta["producto"]
        vendedor = venta["vendedor"]
        total = venta["total"]
        
        # Agrupar por mes
        if mes not in ventas_por_mes:
            ventas_por_mes[mes] = {"total": 0, "cantidad": 0}
        ventas_por_mes[mes]["total"] += total
        ventas_por_mes[mes]["cantidad"] += 1
        
        # Agrupar por producto
        if producto not in ventas_por_producto:
            ventas_por_producto[producto] = {"total": 0, "cantidad": 0}
        ventas_por_producto[producto]["total"] += total
        ventas_por_producto[producto]["cantidad"] += 1
        
        # Agrupar por vendedor
        if vendedor not in ventas_por_vendedor:
            ventas_por_vendedor[vendedor] = {"total": 0, "cantidad": 0}
        ventas_por_vendedor[vendedor]["total"] += total
        ventas_por_vendedor[vendedor]["cantidad"] += 1
    
    # Generar reporte
    print("\n📊 ANÁLISIS DE VENTAS")
    print("=" * 50)
    
    # Reporte por mes
    print("\n📅 VENTAS POR MES:")
    for mes, datos in sorted(ventas_por_mes.items()):
        promedio = datos["total"] / datos["cantidad"]
        print(f"  {mes}: ${datos['total']:,.2f} ({datos['cantidad']} ventas, promedio: ${promedio:.2f})")
    
    # Top 3 productos
    top_productos = sorted(
        ventas_por_producto.items(),
        key=lambda x: x[1]["total"],
        reverse=True
    )[:3]
    
    print(f"\n🏆 TOP 3 PRODUCTOS:")
    for i, (producto, datos) in enumerate(top_productos, 1):
        print(f"  {i}. {producto}: ${datos['total']:,.2f} ({datos['cantidad']} ventas)")
    
    # Top vendedores
    top_vendedores = sorted(
        ventas_por_vendedor.items(),
        key=lambda x: x[1]["total"],
        reverse=True
    )
    
    print(f"\n👑 VENDEDORES POR DESEMPEÑO:")
    for i, (vendedor, datos) in enumerate(top_vendedores, 1):
        print(f"  {i}. {vendedor}: ${datos['total']:,.2f} ({datos['cantidad']} ventas)")

# Datos de ejemplo
ventas_ejemplo = [
    {"fecha": "2024-01-15", "producto": "Laptop", "vendedor": "Ana", "total": 1200},
    {"fecha": "2024-01-20", "producto": "Mouse", "vendedor": "Carlos", "total": 45},
    {"fecha": "2024-01-25", "producto": "Laptop", "vendedor": "Ana", "total": 1200},
    {"fecha": "2024-02-10", "producto": "Teclado", "vendedor": "María", "total": 120},
    {"fecha": "2024-02-15", "producto": "Monitor", "vendedor": "Carlos", "total": 400},
    {"fecha": "2024-02-20", "producto": "Laptop", "vendedor": "Ana", "total": 1200},
]

# Realizar análisis
analizar_ventas(ventas_ejemplo)

Consejos y mejores prácticas

1. Verificación de claves

# ❌ Propenso a errores
def procesar_usuario(usuario):
    nombre = usuario["nombre"]  # KeyError si no existe
    email = usuario["email"]    # KeyError si no existe
    # ...

# ✅ Más seguro
def procesar_usuario_seguro(usuario):
    if "nombre" in usuario and "email" in usuario:
        # Procesar usuario
        print(f"Procesando usuario: {usuario['nombre']}")
    else:
        print("Datos de usuario incompletos")

2. Uso de defaultdict para valores por defecto

from collections import defaultdict

# Contador de palabras
texto = "este es un ejemplo de texto este texto es un ejemplo"
palabras = texto.split()

# ❌ Forma tradicional
contador = {}
for palabra in palabras:
    if palabra in contador:
        contador[palabra] += 1
    else:
        contador[palabra] = 1

# ✅ Con defaultdict
contador_mejorado = defaultdict(int)
for palabra in palabras:
    contador_mejorado[palabra] += 1

print(f"Contador: {dict(contador_mejorado)}")

3. Evitar modificar durante la iteración

# ❌ Error: modificar diccionario durante iteración
productos = {"laptop": 800, "mouse": 25, "teclado": 60}
for producto, precio in productos.items():
    if precio < 100:
        del productos[producto]  # ¡Error! Modifica durante iteración

# ✅ Correcto: crear nuevo diccionario
productos = {"laptop": 800, "mouse": 25, "teclado": 60}
productos_caros = {p: precio for p, precio in productos.items() if precio >= 100}
print(f"Productos caros: {productos_caros}")

🔍 Mi perspectiva: Uno de los errores más comunes que veo en mis estudiantes es modificar un diccionario mientras lo recorren. Esto puede causar comportamientos impredecibles y errores difíciles de depurar. Siempre recomiendo crear un nuevo diccionario con los elementos filtrados en lugar de modificar el original durante la iteración.

Comprueba tu comprensión

Ejercicio 1: Contador de frecuencia

Escribe una función que reciba una cadena de texto y devuelva un diccionario con la frecuencia de cada carácter.

Ver solución
def contar_caracteres(texto):
    """Cuenta la frecuencia de cada carácter en un texto."""
    frecuencia = {}
    
    for caracter in texto:
        if caracter in frecuencia:
            frecuencia[caracter] += 1
        else:
            frecuencia[caracter] = 1
    
    return frecuencia

# Ejemplo de uso
texto = "programación en python"
resultado = contar_caracteres(texto)

print("Frecuencia de caracteres:")
for caracter, cantidad in sorted(resultado.items()):
    print(f"'{caracter}': {cantidad}")

Resultado:

Frecuencia de caracteres:
' ': 2
'a': 2
'c': 1
'e': 1
'g': 1
'h': 1
'i': 1
'm': 1
'n': 2
'o': 2
'p': 2
'r': 2
't': 1
'y': 1
'ó': 1

Ejercicio 2: Fusión de inventarios

Crea una función que combine dos diccionarios de inventario, sumando las cantidades de productos que aparecen en ambos.

Ver solución
def fusionar_inventarios(inv1, inv2):
    """Fusiona dos inventarios sumando las cantidades de productos comunes."""
    resultado = inv1.copy()  # Comenzar con una copia del primer inventario
    
    # Añadir o actualizar con elementos del segundo inventario
    for producto, cantidad in inv2.items():
        if producto in resultado:
            resultado[producto] += cantidad  # Sumar si ya existe
        else:
            resultado[producto] = cantidad   # Añadir si es nuevo
    
    return resultado

# Ejemplo de uso
inventario_almacen1 = {"laptop": 5, "mouse": 10, "teclado": 8}
inventario_almacen2 = {"monitor": 4, "laptop": 3, "impresora": 2}

inventario_total = fusionar_inventarios(inventario_almacen1, inventario_almacen2)

print("Inventario fusionado:")
for producto, cantidad in sorted(inventario_total.items()):
    print(f"- {producto}: {cantidad} unidades")

Resultado:


## Ejercicio 2: Fusión de inventarios

Combina dos inventarios en uno solo, sumando las cantidades de productos duplicados:

```python
# Código para fusionar inventarios
inventario_tienda1 = {
    "laptop": 5,
    "mouse": 10,
    "teclado": 8,
    "monitor": 4
}

inventario_tienda2 = {
    "laptop": 3,
    "impresora": 2,
    "mouse": 0,
    "teclado": 0
}

# Fusionar inventarios
inventario_fusionado = {}

# Agregar todos los productos de la tienda 1
for producto, cantidad in inventario_tienda1.items():
    inventario_fusionado[producto] = cantidad

# Agregar o actualizar con productos de la tienda 2
for producto, cantidad in inventario_tienda2.items():
    if producto in inventario_fusionado:
        inventario_fusionado[producto] += cantidad
    else:
        inventario_fusionado[producto] = cantidad

# Mostrar inventario fusionado
print("Inventario fusionado:")
for producto, cantidad in sorted(inventario_fusionado.items()):
    print(f"- {producto}: {cantidad} unidades")

Ejemplo de salida esperada:

Inventario fusionado:
- impresora: 2 unidades
- laptop: 8 unidades
- monitor: 4 unidades
- mouse: 10 unidades
- teclado: 8 unidades

Ejercicio 3: Análisis de ventas por categoría

Escribe una función que analice un conjunto de ventas y calcule el total vendido por categoría de producto.

Ver solución
# Código para analizar ventas por categoría
def analizar_ventas_por_categoria(ventas, productos):
    """
    Analiza ventas y calcula totales por categoría.
    
    Args:
        ventas: Lista de diccionarios con información de ventas
        productos: Diccionario con información de productos (incluye categoría)
    """
    # Inicializar diccionario para totales por categoría
    totales_por_categoria = {}
    
    # Procesar cada venta
    for venta in ventas:
        producto_id = venta["producto_id"]
        cantidad = venta["cantidad"]
        precio = venta["precio"]
        
        # Obtener categoría del producto
        if producto_id in productos:
            categoria = productos[producto_id]["categoria"]
            
            # Calcular total de esta venta
            total_venta = cantidad * precio
            
            # Actualizar total de la categoría
            if categoria in totales_por_categoria:
                totales_por_categoria[categoria] += total_venta
            else:
                totales_por_categoria[categoria] = total_venta
    
    # Mostrar resultados
    print("Ventas por categoría:")
    for categoria, total in sorted(totales_por_categoria.items()):
        print(f"- {categoria}: ${total:,.2f}")
    
    return totales_por_categoria

# Datos de ejemplo
productos = {
    "p1": {"nombre": "Laptop", "categoria": "Electrónicos"},
    "p2": {"nombre": "Mouse", "categoria": "Accesorios"},
    "p3": {"nombre": "Monitor", "categoria": "Periféricos"},
    "p4": {"nombre": "Teclado", "categoria": "Accesorios"},
    "p5": {"nombre": "Smartphone", "categoria": "Electrónicos"}
}

ventas = [
    {"producto_id": "p1", "cantidad": 3, "precio": 1200.00},
    {"producto_id": "p2", "cantidad": 5, "precio": 25.00},
    {"producto_id": "p3", "cantidad": 2, "precio": 200.00},
    {"producto_id": "p4", "cantidad": 7, "precio": 45.00},
    {"producto_id": "p5", "cantidad": 1, "precio": 300.00}
]

# Ejecutar análisis
analizar_ventas_por_categoria(ventas, productos)

Ejemplo de salida esperada:

Ventas por categoría:
- Accesorios: $365.00
- Electrónicos: $3,900.00
- Periféricos: $400.00
def analizar_ventas_por_categoria(ventas, productos):
    """
    Analiza ventas y calcula totales por categoría.
    
    Args:
        ventas: Lista de diccionarios con información de ventas
        productos: Diccionario con información de productos (incluye categoría)
    
    Returns:
        Diccionario con totales por categoría
    """
    ventas_por_categoria = {}
    
    for venta in ventas:
        codigo_producto = venta["producto"]
        cantidad = venta["cantidad"]
        
        # Obtener información del producto
        if codigo_producto in productos:
            producto_info = productos[codigo_producto]
            categoria = producto_info["categoria"]
            precio = producto_info["precio"]
            
            # Calcular importe de esta venta
            importe = precio * cantidad
            
            # Actualizar total de la categoría
            if categoria in ventas_por_categoria:
                ventas_por_categoria[categoria] += importe
            else:
                ventas_por_categoria[categoria] = importe
    
    return ventas_por_categoria

# Datos de ejemplo
productos = {
    "P001": {"nombre": "Laptop", "precio": 1200, "categoria": "Electrónicos"},
    "P002": {"nombre": "Mouse", "precio": 25, "categoria": "Accesorios"},
    "P003": {"nombre": "Monitor", "precio": 300, "categoria": "Electrónicos"},
    "P004": {"nombre": "Teclado", "precio": 80, "categoria": "Accesorios"},
    "P005": {"nombre": "Impresora", "precio": 200, "categoria": "Periféricos"}
}

ventas = [
    {"producto": "P001", "cantidad": 2, "fecha": "2024-01-15"},
    {"producto": "P002", "cantidad": 5, "fecha": "2024-01-16"},
    {"producto": "P003", "cantidad": 1, "fecha": "2024-01-20"},
    {"producto": "P001", "cantidad": 1, "fecha": "2024-02-05"},
    {"producto": "P004", "cantidad": 3, "fecha": "2024-02-10"},
    {"producto": "P005", "cantidad": 2, "fecha": "2024-02-15"}
]

resultado = analizar_ventas_por_categoria(ventas, productos)

print("\nVentas por categoría:")
for categoria, total in sorted(resultado.items(), key=lambda x: x[1], reverse=True):
    print(f"- {categoria}: ${total:,.2f}")

Resultado:

Ventas por categoría:
- Electrónicos: $3,900.00
- Periféricos: $400.00

Ejercicio 3: Análisis de ventas por categoría

# Ejemplo de salida esperada
print("Ventas por categoría:")
print("- Electrónicos: $3,900.00")
print("- Accesorios: $365.00")
print("- Periféricos: $400.00")

Resumen

Los diccionarios en Python son como un sistema de inventario inteligente en tu almacén de datos:

  • Pares clave-valor: Cada elemento tiene una etiqueta única (clave) y un valor asociado
  • Acceso instantáneo: Búsqueda por clave extremadamente rápida (O(1))
  • Modificables: Puedes añadir, cambiar o eliminar elementos fácilmente
  • Claves únicas: No puede haber claves duplicadas
  • Ordenados: Mantienen el orden de inserción (desde Python 3.7)

Operaciones clave que debes recordar:

  • Crear: {}, dict(), comprensiones de diccionario
  • Acceder: dict[key], get(), setdefault()
  • Modificar: dict[key] = value, update(), pop(), del
  • Iterar: keys(), values(), items()

Los diccionarios son una de las estructuras de datos más poderosas en Python, y dominarlos te permitirá organizar y manipular datos de manera eficiente en tus aplicaciones.


🧭 Navegación:

Capítulos de esta sección: