Listas: Las Estanterías Flexibles
🧭 Navegación:
- Anterior: Introducción a Estructuras de Datos
- Siguiente: Diccionarios
¡Bienvenido a la sección de estanterías de nuestro almacén! En este capítulo, aprenderás sobre las listas, una de las estructuras de datos más versátiles y utilizadas en Python.
📚 Las estanterías inteligentes de tu almacén
Imagina que en tu almacén acabas de instalar un sistema de estanterías modular súper avanzado. Estas estanterías tienen características especiales:
- Se expanden automáticamente cuando necesitas más espacio
- Mantienen el orden exacto de los productos que colocas
- Numeran automáticamente cada posición (empezando desde 0)
- Permiten reorganizar los productos fácilmente
- Aceptan cualquier tipo de producto en cualquier posición
En Python, las listas funcionan exactamente así: son colecciones ordenadas y modificables que pueden contener cualquier tipo de datos.
# Tu estantería modular en acción
productos = ["laptop", "mouse", "teclado", "monitor"]
print("📦 Estantería de productos:")
for posicion, producto in enumerate(productos):
print(f"Posición {posicion}: {producto}")
# Resultado:
# Posición 0: laptop
# Posición 1: mouse
# Posición 2: teclado
# Posición 3: monitor
🔍 Mi perspectiva: Cuando empecé a programar, me costaba entender por qué la primera posición era 0 y no 1. Con el tiempo, me di cuenta de que es como medir distancias: el primer elemento está a 0 pasos del inicio, el segundo a 1 paso, y así sucesivamente. Esta forma de pensar me ayudó mucho.
Características principales de las listas
1. ✅ Ordenadas: Mantienen el orden de inserción
Las listas son como una cinta transportadora que mantiene el orden exacto de los productos:
pasos_proceso = ["recibir", "verificar", "almacenar", "etiquetar", "enviar"]
print(f"Primer paso: {pasos_proceso[0]}") # recibir
print(f"Último paso: {pasos_proceso[-1]}") # enviar
2. ✅ Modificables (Mutables): Puedes cambiar su contenido
Puedes añadir, quitar o cambiar productos en tu estantería en cualquier momento:
inventario = ["laptop", "mouse", "teclado"]
# Añadir un producto nuevo
inventario.append("monitor")
# Cambiar un producto existente
inventario[1] = "mouse_gaming"
print(inventario) # ['laptop', 'mouse_gaming', 'teclado', 'monitor']
3. ✅ Permiten duplicados: El mismo elemento puede aparecer varias veces
A diferencia de otras estructuras, las listas permiten tener múltiples copias del mismo elemento:
pedidos_dia = ["laptop", "mouse", "laptop", "teclado", "laptop"]
print(f"Laptops pedidas hoy: {pedidos_dia.count('laptop')}") # 3
4. ✅ Indexadas: Acceso directo a cualquier posición
Puedes acceder instantáneamente a cualquier producto conociendo su posición:
productos = ["A", "B", "C", "D", "E"]
print(f"Primero: {productos[0]}") # A
print(f"Tercero: {productos[2]}") # C
print(f"Último: {productos[-1]}") # E
Creando tus propias estanterías (listas)
Hay varias formas de crear listas en Python, igual que hay diferentes formas de montar estanterías en un almacén:
Método 1: Estantería vacía lista para llenar
# Estantería completamente vacía
productos = []
inventario = list() # Otra forma de crear una lista vacía
Método 2: Estantería con productos iniciales
# Estantería ya con productos
frutas = ["manzana", "naranja", "plátano", "uva"]
numeros = [1, 2, 3, 4, 5]
Método 3: Estantería con productos variados
Las listas pueden contener cualquier tipo de datos, incluso otras listas:
# Información completa de un producto
producto_info = ["Laptop Dell XPS", 15.6, True, 999.99, ["negro", "plata"]]
print(f"Nombre: {producto_info[0]}")
print(f"Tamaño: {producto_info[1]} pulgadas")
print(f"Disponible: {producto_info[2]}")
print(f"Precio: ${producto_info[3]}")
print(f"Colores disponibles: {producto_info[4][0]} y {producto_info[4][1]}")
Método 4: Estantería con secuencias numéricas
# Crear lista de números con range()
numeros_pares = list(range(0, 11, 2)) # [0, 2, 4, 6, 8, 10]
print(f"Números pares hasta 10: {numeros_pares}")
Método 5: Estantería con generación automática (comprensión de listas)
# Generar lista con una fórmula
cuadrados = [x**2 for x in range(1, 6)] # [1, 4, 9, 16, 25]
print(f"Cuadrados del 1 al 5: {cuadrados}")
Accediendo a los productos en tus estanterías
Acceso por índice: Conocer la posición exacta
productos = ["laptop", "mouse", "teclado", "monitor", "webcam"]
# Índices positivos (desde el inicio)
print(f"Primer producto: {productos[0]}") # laptop
print(f"Tercer producto: {productos[2]}") # teclado
# Índices negativos (desde el final)
print(f"Último producto: {productos[-1]}") # webcam
print(f"Penúltimo producto: {productos[-2]}") # monitor
Slicing: Obtener secciones de estantería
El slicing (rebanado) es como seleccionar una sección completa de tu estantería:
productos = ["A", "B", "C", "D", "E", "F", "G", "H"]
# Sintaxis: lista[inicio:fin:paso]
# (fin no está incluido en el resultado)
# Primeros 3 productos
print(f"Primeros 3: {productos[:3]}") # ['A', 'B', 'C']
# Últimos 3 productos
print(f"Últimos 3: {productos[-3:]}") # ['F', 'G', 'H']
# Del tercero al sexto
print(f"Del 3 al 6: {productos[2:6]}") # ['C', 'D', 'E', 'F']
# Productos en posiciones pares
print(f"Posiciones pares: {productos[::2]}") # ['A', 'C', 'E', 'G']
# Invertir el orden
print(f"Orden inverso: {productos[::-1]}") # ['H', 'G', 'F', 'E', 'D', 'C', 'B', 'A']
🔍 Mi perspectiva: El slicing fue uno de los conceptos que más me costó dominar al principio, pero una vez que lo entiendes, se convierte en una herramienta increíblemente poderosa. Yo lo visualizo como cortar rebanadas de un pan: defines dónde empiezas a cortar, dónde terminas, y qué tan gruesas son las rebanadas.
Operaciones básicas con estanterías
1. Añadir productos a tu estantería
productos = ["laptop", "mouse"]
# append() - Añadir al final de la estantería
productos.append("teclado")
print(productos) # ['laptop', 'mouse', 'teclado']
# insert() - Colocar en una posición específica
productos.insert(1, "monitor") # Insertar en posición 1
print(productos) # ['laptop', 'monitor', 'mouse', 'teclado']
# extend() - Añadir múltiples productos de una vez
nuevos_productos = ["webcam", "altavoces"]
productos.extend(nuevos_productos)
print(productos) # ['laptop', 'monitor', 'mouse', 'teclado', 'webcam', 'altavoces']
2. Quitar productos de tu estantería
productos = ["laptop", "mouse", "teclado", "monitor", "mouse", "webcam"]
# remove() - Quitar la primera ocurrencia de un producto
productos.remove("mouse") # Elimina el primer "mouse"
print(productos) # ['laptop', 'teclado', 'monitor', 'mouse', 'webcam']
# pop() - Quitar y devolver un producto
ultimo = productos.pop() # Quita el último
print(f"Producto retirado: {ultimo}") # webcam
print(productos) # ['laptop', 'teclado', 'monitor', 'mouse']
segundo = productos.pop(1) # Quita el de posición 1
print(f"Producto retirado: {segundo}") # teclado
print(productos) # ['laptop', 'monitor', 'mouse']
# del - Eliminar por índice o sección
del productos[0] # Elimina el primero
print(productos) # ['monitor', 'mouse']
# clear() - Vaciar completamente la estantería
productos_temp = ["a", "b", "c"]
productos_temp.clear()
print(productos_temp) # []
3. Buscar y contar productos
inventario = ["laptop", "mouse", "laptop", "teclado", "mouse", "laptop"]
# count() - Contar cuántas veces aparece un producto
laptops = inventario.count("laptop")
print(f"Laptops en inventario: {laptops}") # 3
# index() - Encontrar la posición de un producto
posicion_mouse = inventario.index("mouse")
print(f"Primer mouse en posición: {posicion_mouse}") # 1
# in - Verificar si un producto existe
if "webcam" in inventario:
print("Tenemos webcams en stock")
else:
print("No tenemos webcams en stock") # Este se ejecuta
4. Organizar tu estantería
# Datos de ejemplo
numeros = [64, 34, 25, 12, 22, 11, 90]
nombres = ["Carlos", "Ana", "Pedro", "María", "Luis"]
# sort() - Ordenar la estantería original
numeros.sort() # Orden ascendente
print(f"Números ordenados: {numeros}") # [11, 12, 22, 25, 34, 64, 90]
nombres.sort(reverse=True) # Orden descendente
print(f"Nombres en orden Z-A: {nombres}") # ['Pedro', 'María', 'Luis', 'Carlos', 'Ana']
# sorted() - Crear una copia ordenada sin modificar la original
precios = [299.99, 49.99, 89.99, 159.99]
precios_ordenados = sorted(precios)
print(f"Precios ordenados: {precios_ordenados}")
print(f"Precios originales: {precios}") # Sin cambios
# reverse() - Invertir el orden
productos = ["A", "B", "C", "D"]
productos.reverse()
print(f"Productos invertidos: {productos}") # ['D', 'C', 'B', 'A']
Técnicas avanzadas para gestionar tus estanterías
1. Comprensiones de listas: La forma elegante de llenar estanterías
Las comprensiones de listas son como tener robots que llenan tu estantería siguiendo reglas específicas:
# Sintaxis: [expresión for elemento in iterable if condición]
# Crear lista de cuadrados
numeros = [1, 2, 3, 4, 5]
cuadrados = [x**2 for x in numeros]
print(f"Cuadrados: {cuadrados}") # [1, 4, 9, 16, 25]
# Filtrar números pares
pares = [x for x in range(1, 11) if x % 2 == 0]
print(f"Números pares: {pares}") # [2, 4, 6, 8, 10]
# Procesar strings
nombres = ["ana", "carlos", "maría", "pedro"]
nombres_titulo = [nombre.title() for nombre in nombres]
print(f"Nombres formateados: {nombres_titulo}") # ['Ana', 'Carlos', 'María', 'Pedro']
2. Listas anidadas: Estanterías con compartimentos
Las listas anidadas son como estanterías con compartimentos o cajones, cada uno conteniendo su propia colección de elementos:
# Crear matriz 3x3 (como una estantería con 3 niveles y 3 compartimentos por nivel)
matriz = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
# Acceder a elementos específicos
print(f"Elemento en fila 1, columna 2: {matriz[1][2]}") # 6
# Ejemplo práctico: inventario por categorías
inventario_tienda = [
["Laptop Dell", "Laptop HP", "Laptop Lenovo"], # Laptops
["Mouse Logitech", "Mouse Razer"], # Mouses
["Teclado mecánico", "Teclado inalámbrico"] # Teclados
]
print("📦 Inventario por categorías:")
categorias = ["Laptops", "Mouses", "Teclados"]
for i, categoria in enumerate(categorias):
print(f"\n{categoria}:")
for producto in inventario_tienda[i]:
print(f" - {producto}")
3. Operaciones matemáticas con listas
# Datos de ventas mensuales
ventas = [1200, 1500, 1800, 1400, 1600, 2000, 1750, 1900, 1650, 1800, 2100, 2300]
# Operaciones básicas
total_ventas = sum(ventas)
promedio = sum(ventas) / len(ventas)
maximo = max(ventas)
minimo = min(ventas)
print(f"📊 Análisis de ventas anuales:")
print(f" Total: ${total_ventas:,}")
print(f" Promedio mensual: ${promedio:,.2f}")
print(f" Mejor mes: ${maximo:,}")
print(f" Peor mes: ${minimo:,}")
# Encontrar posiciones de máximo y mínimo
mes_mejor = ventas.index(maximo) + 1 # +1 porque los meses empiezan en 1
mes_peor = ventas.index(minimo) + 1
print(f" El mejor mes fue el mes {mes_mejor}")
print(f" El peor mes fue el mes {mes_peor}")
Aplicaciones prácticas de las listas
1. Sistema de gestión de inventario
def gestionar_inventario():
"""Sistema simple de gestión de inventario usando listas"""
# Inventario inicial
inventario = [
{"id": 1, "nombre": "Laptop", "stock": 5, "precio": 800},
{"id": 2, "nombre": "Mouse", "stock": 10, "precio": 25},
{"id": 3, "nombre": "Teclado", "stock": 8, "precio": 60}
]
# Mostrar inventario actual
print("\n📦 INVENTARIO ACTUAL:")
print("-" * 50)
print(f"{'ID':<5}{'PRODUCTO':<15}{'STOCK':<10}{'PRECIO':<10}{'VALOR':<10}")
print("-" * 50)
valor_total = 0
for item in inventario:
valor_item = item["stock"] * item["precio"]
valor_total += valor_item
print(f"{item['id']:<5}{item['nombre']:<15}{item['stock']:<10}${item['precio']:<9}${valor_item:<9}")
print("-" * 50)
print(f"Valor total del inventario: ${valor_total:,.2f}")
# Productos con poco stock (menos de 10 unidades)
poco_stock = [item["nombre"] for item in inventario if item["stock"] < 10]
print(f"\n⚠️ Productos con poco stock: {', '.join(poco_stock)}")
# Producto más caro
producto_mas_caro = max(inventario, key=lambda x: x["precio"])
print(f"💰 Producto más caro: {producto_mas_caro['nombre']} (${producto_mas_caro['precio']})")
# Ejecutar el sistema
gestionar_inventario()
2. Análisis de datos de ventas
def analizar_ventas(datos_ventas):
"""Analiza datos de ventas y genera reporte usando listas"""
# Extraer información
productos = [venta["producto"] for venta in datos_ventas]
cantidades = [venta["cantidad"] for venta in datos_ventas]
precios = [venta["precio"] for venta in datos_ventas]
totales = [venta["cantidad"] * venta["precio"] for venta in datos_ventas]
# Análisis básico
total_ingresos = sum(totales)
venta_promedio = sum(totales) / len(totales)
producto_mas_vendido = max(set(productos), key=productos.count)
# Top 3 ventas más altas
ventas_con_total = [(datos_ventas[i], totales[i]) for i in range(len(datos_ventas))]
top_ventas = sorted(ventas_con_total, key=lambda x: x[1], reverse=True)[:3]
# Generar reporte
print("\n📊 REPORTE DE VENTAS")
print("=" * 50)
print(f"Total de transacciones: {len(datos_ventas)}")
print(f"Ingresos totales: ${total_ingresos:,.2f}")
print(f"Venta promedio: ${venta_promedio:.2f}")
print(f"Producto más vendido: {producto_mas_vendido}")
print(f"\n🏆 Top 3 ventas más altas:")
for i, (venta, total) in enumerate(top_ventas, 1):
print(f" {i}. {venta['producto']} - ${total:.2f}")
# Datos de ejemplo
ventas_mes = [
{"producto": "Laptop", "cantidad": 2, "precio": 800},
{"producto": "Mouse", "cantidad": 5, "precio": 25},
{"producto": "Teclado", "cantidad": 3, "precio": 60},
{"producto": "Laptop", "cantidad": 1, "precio": 800},
{"producto": "Monitor", "cantidad": 2, "precio": 300},
{"producto": "Mouse", "cantidad": 10, "precio": 25}
]
analizar_ventas(ventas_mes)
Consejos y mejores prácticas
1. Rendimiento y eficiencia
# ✅ Bueno: usar comprensiones de lista
numeros_pares = [x for x in range(1000) if x % 2 == 0]
# ❌ Menos eficiente: bucle tradicional con append
numeros_pares = []
for x in range(1000):
if x % 2 == 0:
numeros_pares.append(x)
# ✅ Bueno: usar extend() para añadir múltiples elementos
lista.extend([1, 2, 3, 4])
# ❌ Menos eficiente: múltiples append()
lista.append(1)
lista.append(2)
lista.append(3)
lista.append(4)
2. Evitar errores comunes
# ❌ Error: modificar lista mientras se itera
numeros = [1, 2, 3, 4, 5]
for numero in numeros:
if numero % 2 == 0:
numeros.remove(numero) # ¡Problemático!
# ✅ Correcto: crear nueva lista
numeros = [1, 2, 3, 4, 5]
numeros_impares = [n for n in numeros if n % 2 != 0]
# ❌ Error: no verificar índices
lista = [1, 2, 3]
# print(lista[5]) # IndexError!
# ✅ Correcto: verificar antes de acceder
if 5 < len(lista):
print(lista[5])
else:
print("Índice fuera de rango")
🔍 Mi perspectiva: Uno de los errores más comunes que veo en mis estudiantes es modificar una lista mientras la recorren. Esto puede causar comportamientos inesperados porque los índices cambian durante la iteración. Siempre recomiendo crear una nueva lista en lugar de modificar la original durante un bucle.
Comprueba tu comprensión
Ejercicio 1: Filtrado de productos
Escribe una función que, dada una lista de productos con sus precios, devuelva una nueva lista con los productos que cuestan menos de 50 dólares.
Ver solución
def filtrar_productos_economicos(productos):
return [producto for producto in productos if producto["precio"] < 50]
# Ejemplo de uso
inventario = [
{"nombre": "Teclado", "precio": 45.99},
{"nombre": "Monitor", "precio": 199.99},
{"nombre": "Mouse", "precio": 25.50},
{"nombre": "Disco duro", "precio": 89.99},
{"nombre": "Webcam", "precio": 39.99}
]
productos_economicos = filtrar_productos_economicos(inventario)
print("Productos económicos:")
for producto in productos_economicos:
print(f"- {producto['nombre']}: ${producto['precio']}")
Resultado:
Productos económicos:
- Teclado: $45.99
- Mouse: $25.5
- Webcam: $39.99
Ejercicio 2: Organización de inventario
Crea una función que organice una lista de productos en categorías, utilizando listas anidadas.
Ver solución
def organizar_por_categorias(productos):
categorias = {}
# Agrupar productos por categoría
for producto in productos:
categoria = producto["categoria"]
if categoria not in categorias:
categorias[categoria] = []
categorias[categoria].append(producto["nombre"])
# Convertir a lista de listas
resultado = []
for categoria, productos in categorias.items():
resultado.append([categoria, productos])
return resultado
# Ejemplo de uso
productos = [
{"nombre": "Laptop Dell", "categoria": "Computadoras"},
{"nombre": "Mouse Logitech", "categoria": "Accesorios"},
{"nombre": "Teclado Mecánico", "categoria": "Accesorios"},
{"nombre": "Monitor LG", "categoria": "Monitores"},
{"nombre": "Laptop HP", "categoria": "Computadoras"}
]
inventario_organizado = organizar_por_categorias(productos)
print("Inventario por categorías:")
for categoria in inventario_organizado:
print(f"\n{categoria[0]}:")
for producto in categoria[1]:
print(f" - {producto}")
Resultado:
Inventario por categorías:
Computadoras:
- Laptop Dell
- Laptop HP
Accesorios:
- Mouse Logitech
- Teclado Mecánico
Monitores:
- Monitor LG
Ejercicio 3: Análisis de ventas semanales
Analiza las ventas semanales de una tienda y calcula estadísticas importantes:
# Código para analizar ventas semanales
ventas_semana = {
"Lunes": 1200.50,
"Martes": 890.75,
"Miércoles": 1300.25,
"Jueves": 1500.80,
"Viernes": 2100.00,
"Sábado": 1850.50,
"Domingo": 900.00
}
# Calcular estadísticas
total_ventas = sum(ventas_semana.values())
dias = len(ventas_semana)
promedio = total_ventas / dias
# Encontrar días por encima del promedio
dias_buenos = [dia for dia, venta in ventas_semana.items() if venta > promedio]
# Encontrar mejor y peor día
mejor_dia = max(ventas_semana.items(), key=lambda x: x[1])
peor_dia = min(ventas_semana.items(), key=lambda x: x[1])
# Mostrar resultados
print("📊 ANÁLISIS DE VENTAS SEMANALES")
print(f"Promedio de ventas: ${promedio:.2f}")
print(f"Días por encima del promedio: {', '.join(dias_buenos)}")
print(f"Mejor día: {mejor_dia[0]} (${mejor_dia[1]:.2f})")
print(f"Peor día: {peor_dia[0]} (${peor_dia[1]:.2f})")
Ejemplo de salida esperada:
📊 ANÁLISIS DE VENTAS SEMANALES
Promedio de ventas: $1,428.57
Días por encima del promedio: Jueves, Viernes, Sábado
Mejor día: Viernes ($2,100.00)
Peor día: Domingo ($900.00)
Ejercicio 3: Análisis de ventas semanales
Escribe una función que analice las ventas diarias de una semana y calcule: el día con más ventas, el día con menos ventas, y el promedio de ventas.
Ver solución
def analizar_ventas_semanales(ventas):
dias = ["Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"]
# Verificar que tenemos datos para 7 días
if len(ventas) != 7:
return "Error: Se necesitan datos de 7 días"
# Calcular estadísticas
total = sum(ventas)
promedio = total / 7
max_ventas = max(ventas)
min_ventas = min(ventas)
dia_max = dias[ventas.index(max_ventas)]
dia_min = dias[ventas.index(min_ventas)]
# Días por encima del promedio
dias_buenos = [dias[i] for i, venta in enumerate(ventas) if venta > promedio]
return {
"total": total,
"promedio": promedio,
"mejor_dia": dia_max,
"peor_dia": dia_min,
"ventas_max": max_ventas,
"ventas_min": min_ventas,
"dias_buenos": dias_buenos
}
# Ejemplo de uso
ventas_semana = [1200, 980, 1100, 1500, 2100, 1800, 900]
resultado = analizar_ventas_semanales(ventas_semana)
print("\n📊 ANÁLISIS DE VENTAS SEMANALES")
print(f"Total de ventas: ${resultado['total']:,.2f}")
print(f"Promedio diario: ${resultado['promedio']:,.2f}")
print(f"Mejor día: {resultado['mejor_dia']} (${resultado['ventas_max']:,.2f})")
print(f"Peor día: {resultado['peor_dia']} (${resultado['ventas_min']:,.2f})")
print(f"Días por encima del promedio: {', '.join(resultado['dias_buenos'])}")
Resultado:
📊 ANÁLISIS DE VENTAS SEMANALES
Total de ventas: $9,580.00
Promedio diario: $1,368.57
Mejor día: Viernes ($2,100.00)
Peor día: Domingo ($900.00)
Días por encima del promedio: Miércoles, Jueves, Viernes, Sábado
Resumen
Las listas en Python son como estanterías flexibles en tu almacén de datos:
- ✅ Ordenadas: Mantienen el orden de los elementos
- ✅ Modificables: Puedes añadir, quitar o cambiar elementos
- ✅ Indexadas: Acceso directo a cualquier posición
- ✅ Permiten duplicados: El mismo valor puede aparecer varias veces
Operaciones clave que debes recordar:
- Crear:
[]
,list()
, comprensiones de lista - Acceder:
lista[índice]
,lista[inicio:fin:paso]
- Añadir:
append()
,insert()
,extend()
- Eliminar:
remove()
,pop()
,del
,clear()
- Buscar:
index()
,count()
,in
- Ordenar:
sort()
,sorted()
,reverse()
Las listas son una de las herramientas más versátiles en Python, y dominarlas te permitirá resolver una amplia variedad de problemas de programación de manera eficiente.
🧭 Navegación:
- Anterior: Introducción a Estructuras de Datos
- Siguiente: Diccionarios
Capítulos de esta sección:
- Introducción a Estructuras de Datos
- Listas (página actual)
- Diccionarios
- Tuplas
- Conjuntos (Sets)
- Quiz: Estructuras de Datos