Bucles en Python: for y while – Guía completa 2025 [+Ejemplos]

Contenido
- 1 ¿Qué son los bucles en programación?
- 2 Bucle for en Python: sintaxis básica
- 3 Bucle for con range() en Python
- 4 Bucle for con enumerate()
- 5 Bucles for anidados en Python
- 6 List comprehensions: for en una línea
- 7 Bucle while en Python: sintaxis básica
- 8 for vs while: ¿cuál usar?
- 9 break, continue y else en bucles
- 10 Bucles while con condiciones complejas
- 11 Bucle while infinito en Python
- 12 Bucles while anidados
- 13 Contador y acumulador en while
- 14 Bucles for con diccionarios
- 15 Casos de uso reales de bucles
- 16 Errores comunes con bucles
- 17 Optimización de bucles: mejores prácticas
- 18 Puntos clave para recordar
¿Qué son los bucles en programación?
Los bucles (también llamados iteraciones o loops) son estructuras que permiten ejecutar un bloque de código múltiples veces. Son fundamentales en programación porque automatizan tareas repetitivas y te permiten procesar colecciones de datos de forma eficiente.
Imagina que necesitas enviar un email a 1000 clientes. Sin bucles, tendrías que escribir el mismo código 1000 veces. Con un bucle, escribes el código una vez y lo ejecutas automáticamente tantas veces como necesites.
Python ofrece dos tipos principales de bucles:
- Bucle for – itera sobre una secuencia (lista, tupla, string, range, etc.)
- Bucle while – repite mientras una condición sea verdadera
Cada tipo tiene sus casos de uso específicos. En este artículo aprenderás cuándo y cómo usar cada uno, junto con técnicas avanzadas como bucles anidados, break, continue y else.
Bucle for en Python: sintaxis básica
El bucle for en Python está diseñado para iterar sobre secuencias. A diferencia de otros lenguajes donde for se basa en contadores, en Python el for recorre directamente los elementos de una colección.

Sintaxis
for variable in iterable:
# código que se ejecuta en cada iteración
instruccion1
instruccion2Elementos clave:
variable– toma el valor de cada elemento en cada iteracióniterable– cualquier objeto que se pueda recorrer (lista, tupla, string, range, etc.)- Los dos puntos
:son obligatorios - El bloque debe estar indentado (4 espacios según PEP 8)
Ejemplo básico – Iterar sobre una lista
>>> fruits = ["apple", "banana", "orange", "grape"]
>>> for fruit in fruits:
... print(f"Me gusta la {fruit}")
Me gusta la apple
Me gusta la banana
Me gusta la orange
Me gusta la grapeIterar sobre strings
Los strings son iterables carácter por carácter:
>>> word = "Python"
>>> for letter in word:
... print(letter)
P
y
t
h
o
nCaso real – Procesar lista de precios
Imaginemos que tenemos una tienda online y necesitamos aplicar un descuento del 20% a todos los productos para una promoción especial. Usando un bucle for, podemos procesar cada precio y calcular su valor con descuento:
>>> prices = [100, 250, 75, 500, 150]
>>> discounted_prices = []
>>> discount_rate = 0.20
>>>
>>> for price in prices:
... discounted = price * (1 - discount_rate)
... discounted_prices.append(discounted)
... print(f"Precio original: ${price} → Con descuento: ${discounted}")
Precio original: $100 → Con descuento: $80.0
Precio original: $250 → Con descuento: $200.0
Precio original: $75 → Con descuento: $60.0
Precio original: $500 → Con descuento: $400.0
Precio original: $150 → Con descuento: $120.0
>>>
>>> print(f"Precios con descuento: {discounted_prices}")
Precios con descuento: [80.0, 200.0, 60.0, 400.0, 120.0]Bucle for con range() en Python
La función range() genera una secuencia de números, siendo extremadamente útil cuando necesitas repetir código un número específico de veces o iterar con índices.
Las tres formas de range()
range(stop) # De 0 hasta stop-1
range(start, stop) # De start hasta stop-1
range(start, stop, step) # De start hasta stop-1, en pasos de stepEjemplo básico – Contador del 1 al 10
>>> for number in range(1, 11):
... print(f"Número: {number}")
Número: 1
Número: 2
Número: 3
Número: 4
Número: 5
Número: 6
Número: 7
Número: 8
Número: 9
Número: 10Cuenta regresiva
>>> for count in range(10, 0, -1):
... print(count)
>>> print("¡Despegue!")
10
9
8
7
6
5
4
3
2
1
¡Despegue!Iterar con paso personalizado
>>> # Números pares del 0 al 20
>>> for even in range(0, 21, 2):
... print(even, end=" ")
0 2 4 6 8 10 12 14 16 18 20Caso real – Generador de tabla de multiplicar
Vamos a crear un programa que genere la tabla de multiplicar de cualquier número. Esto es útil para aplicaciones educativas o cuando necesitas mostrar relaciones matemáticas:
>>> number = 7
>>> print(f"Tabla del {number}:")
>>> for i in range(1, 11):
... result = number * i
... print(f"{number} x {i} = {result}")
Tabla del 7:
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70Bucle for con enumerate()
La función enumerate() permite obtener simultáneamente el índice y el valor de cada elemento mientras iteras. Es extremadamente útil cuando necesitas saber la posición del elemento.

Sintaxis
for index, value in enumerate(iterable, start=0):
# código usando index y valueEjemplo básico – Lista numerada
>>> tasks = ["Comprar leche", "Llamar al médico", "Hacer ejercicio"]
>>> for index, task in enumerate(tasks, start=1):
... print(f"{index}. {task}")
1. Comprar leche
2. Llamar al médico
3. Hacer ejercicioCaso real – Procesar archivo con números de línea
Cuando procesamos archivos de log o cualquier documento de texto, es muy útil tener el número de línea junto al contenido. Aquí simulamos la lectura de un archivo y mostramos cada línea con su número:
>>> lines = ["primera línea", "segunda línea", "tercera línea"]
>>> for line_number, content in enumerate(lines, start=1):
... print(f"Línea {line_number}: {content.upper()}")
Línea 1: PRIMERA LÍNEA
Línea 2: SEGUNDA LÍNEA
Línea 3: TERCERA LÍNEABucles for anidados en Python
Un bucle anidado es un bucle dentro de otro bucle. El bucle interior se ejecuta completamente por cada iteración del bucle exterior.
Sintaxis básica
for variable_exterior in iterable_exterior:
for variable_interior in iterable_interior:
# código que usa ambas variablesEjemplo básico – Tabla de multiplicar completa
>>> for i in range(1, 4):
... for j in range(1, 4):
... result = i * j
... print(f"{i} x {j} = {result}")
... print("---") # Separador
1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
---
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
---
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
---Caso real – Generar combinaciones de productos
En un e-commerce, necesitas saber todas las posibles combinaciones de un producto. Por ejemplo, una camiseta disponible en diferentes tallas y colores. Los bucles anidados son perfectos para generar todas estas variantes:
>>> sizes = ["S", "M", "L", "XL"]
>>> colors = ["Rojo", "Azul", "Negro"]
>>>
>>> print("Combinaciones disponibles:")
>>> product_combinations = []
>>> for size in sizes:
... for color in colors:
... combination = f"{color} - Talla {size}"
... product_combinations.append(combination)
... print(f"- {combination}")
Combinaciones disponibles:
- Rojo - Talla S
- Azul - Talla S
- Negro - Talla S
- Rojo - Talla M
- Azul - Talla M
- Negro - Talla M
- Rojo - Talla L
- Azul - Talla L
- Negro - Talla L
- Rojo - Talla XL
- Azul - Talla XL
- Negro - Talla XL
>>>
>>> print(f"\nTotal combinaciones: {len(product_combinations)}")
Total combinaciones: 12Complejidad de bucles anidados
Importante: Los bucles anidados aumentan exponencialmente el número de operaciones. Un bucle de N elementos dentro de otro de M elementos ejecuta N × M operaciones (complejidad O(n²)).
>>> # Ejemplo de complejidad O(n²)
>>> numbers = [1, 2, 3, 4, 5]
>>> execution_count = 0
>>>
>>> for i in numbers:
... for j in numbers:
... execution_count += 1
>>>
>>> print(f"Elementos: {len(numbers)}")
>>> print(f"Ejecuciones: {execution_count}")
>>> print(f"Complejidad: {len(numbers)} x {len(numbers)} = {execution_count}")
Elementos: 5
Ejecuciones: 25
Complejidad: 5 x 5 = 25List comprehensions: for en una línea
Las list comprehensions son una forma compacta y pythónica de crear listas usando un bucle for en una sola línea.
Sintaxis
nueva_lista = [expresion for elemento in iterable if condicion]Ejemplo básico – Números al cuadrado
>>> # Forma tradicional
>>> squares = []
>>> for number in range(1, 6):
... squares.append(number ** 2)
>>> squares
[1, 4, 9, 16, 25]
>>>
>>> # Con list comprehension
>>> squares = [number ** 2 for number in range(1, 6)]
>>> squares
[1, 4, 9, 16, 25]Con condición – Filtrar números pares
>>> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> even_numbers = [num for num in numbers if num % 2 == 0]
>>> even_numbers
[2, 4, 6, 8, 10]Caso real – Procesar lista de precios
Las list comprehensions son perfectas para transformar datos. Aquí aplicamos un descuento condicional: 20% de descuento solo a productos que cuesten más de 100 euros:
>>> prices = [100, 250, 75, 500, 150]
>>>
>>> # Aplicar 20% descuento solo a precios mayores a 100
>>> discounted = [price * 0.8 if price > 100 else price for price in prices]
>>> discounted
[100, 200.0, 75, 400.0, 120.0]Cuándo NO usar list comprehensions
Evita list comprehensions cuando:
- La lógica es compleja (más de 2-3 operaciones)
- Reduces la legibilidad
- Necesitas efectos secundarios (print, modificar variables externas)
# Malo (demasiado complejo)
result = [item.upper().strip().replace(" ", "_") for item in items if len(item) > 5 and item.startswith("a")]
# Mejor (usar bucle tradicional)
result = []
for item in items:
if len(item) > 5 and item.startswith("a"):
processed = item.upper().strip().replace(" ", "_")
result.append(processed)Bucle while en Python: sintaxis básica
El bucle while repite código mientras una condición sea verdadera. A diferencia del for que itera sobre una secuencia conocida, el while continúa hasta que la condición se vuelve falsa.

Sintaxis
while condicion:
# código que se ejecuta mientras condicion sea True
instruccion1
instruccion2Importante: Debes asegurarte de que la condición eventualmente se vuelva False, o tendrás un bucle infinito.
Ejemplo básico – Contador simple
>>> counter = 1
>>> while counter <= 5:
... print(f"Contador: {counter}")
... counter += 1
Contador: 1
Contador: 2
Contador: 3
Contador: 4
Contador: 5Diferencia fundamental con for
>>> # FOR: sabemos cuántas iteraciones haremos
>>> for i in range(5):
... print(f"Iteración {i}")
>>>
>>> # WHILE: depende de una condición que puede cambiar
>>> user_input = ""
>>> while user_input != "salir":
... user_input = input("Escribe 'salir' para terminar: ")
... print(f"Escribiste: {user_input}")Caso real – Validación de input de usuario
Los bucles while son ideales cuando no sabes cuántas veces necesitarás repetir algo. Aquí creamos un sistema de validación que sigue pidiendo una contraseña hasta que cumpla los requisitos mínimos:
>>> valid_input = False
>>> attempts = 0
>>> max_attempts = 3
>>>
>>> while not valid_input and attempts < max_attempts:
... password = input("Ingresa tu contraseña: ")
... if len(password) >= 8:
... print("Contraseña válida")
... valid_input = True
... else:
... attempts += 1
... remaining = max_attempts - attempts
... print(f"Contraseña muy corta. Intentos restantes: {remaining}")
>>>
>>> if not valid_input:
... print("Máximo de intentos alcanzado")for vs while: ¿cuál usar?
Elegir entre for y while es una de las decisiones más frecuentes al programar. Aquí está la guía definitiva:
Usa for cuando:
- Sabes cuántas iteraciones necesitas
for i in range(10): # Exactamente 10 veces
print(i)- Iteras sobre una colección conocida
for product in products: # Procesar todos los productos
process(product)- Usas índices secuenciales
for index in range(len(items)):
print(f"Item {index}: {items[index]}")Usa while cuando:
- No sabes cuántas iteraciones necesitarás
while user_wants_to_continue(): # Hasta que el usuario decida parar
do_something()- La condición de parada es compleja
while connection_active and data_available and not error_occurred:
process_data()- Necesitas un bucle infinito con break interno
while True:
command = get_command()
if command == "exit":
break
execute(command)Tabla comparativa
| Criterio | for | while |
|---|---|---|
| Iteraciones conocidas | ✓ Ideal | ✗ No recomendado |
| Iteraciones desconocidas | ✗ Difícil | ✓ Ideal |
| Iterar colecciones | ✓ Perfecto | ✗ Innecesario |
| Condiciones complejas | ✗ Limitado | ✓ Flexible |
| Bucles infinitos | ✗ No aplica | ✓ Posible |
| Legibilidad | ✓ Alta | ~ Media |
| Riesgo bucle infinito | ✗ Bajo | ✓ Alto |
Caso comparativo – Mismo problema, dos enfoques
Encontrar el primer número divisible por 7 en una lista:
>>> numbers = [10, 15, 21, 28, 30, 35]
>>>
>>> # Con for
>>> found = None
>>> for number in numbers:
... if number % 7 == 0:
... found = number
... break
>>> print(f"Encontrado con for: {found}")
Encontrado con for: 21
>>>
>>> # Con while
>>> index = 0
>>> found = None
>>> while index < len(numbers) and found is None:
... if numbers[index] % 7 == 0:
... found = numbers[index]
... index += 1
>>> print(f"Encontrado con while: {found}")
Encontrado con while: 21En este caso, for es más legible y pythónico.
break, continue y else en bucles
Python ofrece tres palabras clave para controlar el flujo dentro de los bucles: break, continue y else.

break – Salir del bucle inmediatamente
>>> # Buscar elemento en lista
>>> items = ["apple", "banana", "orange", "grape"]
>>> search_item = "orange"
>>>
>>> for item in items:
... print(f"Revisando: {item}")
... if item == search_item:
... print(f"¡Encontrado! {item}")
... break # Sale del bucle inmediatamente
>>> else:
... print("No encontrado")
Revisando: apple
Revisando: banana
Revisando: orange
¡Encontrado! orangecontinue – Saltar a la siguiente iteración
>>> # Procesar solo números pares
>>> for number in range(1, 11):
... if number % 2 != 0:
... continue # Salta números impares
... print(f"Número par: {number}")
Número par: 2
Número par: 4
Número par: 6
Número par: 8
Número par: 10else en bucles – Ejecutar si NO se usó break
Esta es una característica única de Python que muchos programadores desconocen:
>>> # Verificar si una lista contiene solo números positivos
>>> numbers = [5, 10, 15, 20]
>>>
>>> for num in numbers:
... if num < 0:
... print("Encontrado número negativo")
... break
... else:
... print("Todos los números son positivos")
Todos los números son positivosCaso real – Sistema de login con intentos limitados
>>> max_attempts = 3
>>> correct_password = "python123"
>>>
>>> for attempt in range(1, max_attempts + 1):
... password = input(f"Intento {attempt}/{max_attempts} - Contraseña: ")
... if password == correct_password:
... print("¡Acceso concedido!")
... break
... else:
... remaining = max_attempts - attempt
... if remaining > 0:
... print(f"Contraseña incorrecta. {remaining} intentos restantes")
... else:
... print("Máximo de intentos alcanzado. Cuenta bloqueada.")Llevando los bucles al siguiente nivel
En el libro Python a fondo encontrarás patrones avanzados de bucles, optimización de rendimiento y técnicas profesionales para procesar grandes volúmenes de datos eficientemente.
Bucles while con condiciones complejas
Los bucles while brillan cuando necesitas evaluar múltiples condiciones o condiciones que cambian dinámicamente.
Múltiples condiciones con and/or
>>> balance = 100
>>> attempts = 0
>>> max_attempts = 3
>>> withdrawal_successful = False
>>>
>>> while balance > 0 and attempts < max_attempts and not withdrawal_successful:
... amount = int(input("Cantidad a retirar: "))
... if amount <= balance:
... balance -= amount
... print(f"Retiro exitoso. Balance: ${balance}")
... withdrawal_successful = True
... else:
... attempts += 1
... print(f"Fondos insuficientes. Intento {attempts}/{max_attempts}")
>>>
>>> if not withdrawal_successful:
... print("Operación cancelada")Caso real – Juego de adivinanza
Vamos a crear un juego simple donde el usuario debe adivinar un número. Este es un ejemplo perfecto de cuándo usar while porque no sabemos cuántos intentos necesitará el jugador:
>>> import random
>>> secret_number = random.randint(1, 100)
>>> attempts = 0
>>> max_attempts = 7
>>> guessed = False
>>>
>>> print("Adivina el número entre 1 y 100")
>>>
>>> while attempts < max_attempts and not guessed:
... guess = int(input(f"Intento {attempts + 1}/{max_attempts}: "))
... attempts += 1
...
... if guess == secret_number:
... print(f"¡Correcto! Lo adivinaste en {attempts} intentos")
... guessed = True
... elif guess < secret_number:
... print("Muy bajo. Intenta con un número mayor")
... else:
... print("Muy alto. Intenta con un número menor")
>>>
>>> if not guessed:
... print(f"Se acabaron los intentos. El número era {secret_number}")Bucle while infinito en Python
Un bucle while True: crea un bucle infinito intencionalmente. Es útil para servicios, menús interactivos o procesos que deben correr indefinidamente.
Sintaxis
while True:
# código que se repite indefinidamente
if condicion_de_salida:
break # Única forma de salirEjemplo básico – Menú de aplicación
>>> while True:
... print("\n=== MENÚ ===")
... print("1. Opción A")
... print("2. Opción B")
... print("3. Salir")
...
... choice = input("Selecciona una opción: ")
...
... if choice == "1":
... print("Ejecutando opción A...")
... elif choice == "2":
... print("Ejecutando opción B...")
... elif choice == "3":
... print("¡Hasta luego!")
... break
... else:
... print("Opción inválida")Caso real – Servidor simple que escucha conexiones
Los bucles infinitos son útiles para servicios que deben estar siempre activos. Aquí simulamos un servidor que acepta conexiones hasta alcanzar un límite o recibir un comando de parada:
>>> # Simulación de un servidor
>>> active = True
>>> connection_count = 0
>>> max_connections = 5
>>>
>>> while True:
... # Simular espera de conexión
... command = input("Comando (connect/stop): ")
...
... if command == "connect":
... connection_count += 1
... print(f"Cliente conectado. Total: {connection_count}")
...
... if connection_count >= max_connections:
... print("Máximo de conexiones alcanzado")
... break
... elif command == "stop":
... print(f"Servidor detenido. Total conexiones: {connection_count}")
... break
... else:
... print("Comando no reconocido")Cuándo usar while True
Usa while True para:
- Menús interactivos de consola
- Servicios que escuchan conexiones
- Procesamiento continuo de eventos
- Servidores o daemons
Evita while True cuando:
- Puedas expresar la condición de parada claramente
- Estés aprendiendo (fácil olvidar el break)
- El bucle debe terminar con certeza
Bucles while anidados
Al igual que con for, puedes anidar bucles while, pero debes tener especial cuidado con las condiciones de salida.
>>> main_menu_active = True
>>>
>>> while main_menu_active:
... print("\n=== MENÚ PRINCIPAL ===")
... print("1. Configuración")
... print("2. Salir")
...
... choice = input("Opción: ")
...
... if choice == "1":
... config_menu_active = True
... while config_menu_active:
... print("\n--- Configuración ---")
... print("a. Cambiar idioma")
... print("b. Volver")
...
... sub_choice = input("Opción: ")
...
... if sub_choice == "a":
... print("Idioma cambiado")
... elif sub_choice == "b":
... config_menu_active = False
... elif choice == "2":
... print("¡Adiós!")
... main_menu_active = FalseAdvertencia: Los bucles while anidados son propensos a errores. Es fácil crear bucles infinitos accidentales. Considera usar funciones para organizar mejor el código.
Contador y acumulador en while
Dos patrones fundamentales al usar while son el contador y el acumulador.
Patrón contador
El patrón contador es fundamental cuando necesitas contar cuántos elementos cumplen cierta condición. Aquí contamos cuántos números de una lista son mayores a 10:
>>> numbers = [5, 12, 8, 15, 20, 3, 18]
>>> index = 0
>>> count_greater_than_10 = 0
>>>
>>> while index < len(numbers):
... if numbers[index] > 10:
... count_greater_than_10 += 1
... index += 1
>>>
>>> print(f"Números mayores a 10: {count_greater_than_10}")
Números mayores a 10: 4Patrón acumulador
El acumulador suma, multiplica o concatena valores progresivamente. Es esencial para calcular totales, promedios o construir strings. Aquí calculamos la suma total y el promedio de una lista de números:
>>> numbers = [10, 20, 30, 40, 50]
>>> index = 0
>>> total_sum = 0
>>>
>>> while index < len(numbers):
... total_sum += numbers[index]
... index += 1
>>>
>>> average = total_sum / len(numbers)
>>> print(f"Suma total: {total_sum}")
>>> print(f"Promedio: {average}")
Suma total: 150
Promedio: 30.0Caso real – Calcular promedio de notas con validación
Combinando ambos patrones, creamos un programa que solicita notas al usuario, valida que estén en el rango correcto, y calcula el promedio final. Es un ejemplo perfecto de cómo usar while True con break:
>>> print("Ingresa notas (escribe -1 para terminar)")
>>> total = 0
>>> count = 0
>>>
>>> while True:
... grade = float(input("Nota: "))
...
... if grade == -1:
... break
...
... if 0 <= grade <= 10:
... total += grade
... count += 1
... else:
... print("Nota inválida (debe estar entre 0 y 10)")
>>>
>>> if count > 0:
... average = total / count
... print(f"\nNotas ingresadas: {count}")
... print(f"Promedio: {average:.2f}")
... else:
... print("No se ingresaron notas válidas")Bucles for con diccionarios
Los diccionarios ofrecen tres formas de iteración: claves, valores o pares clave-valor.
Iterar sobre claves (por defecto)
>>> user_data = {
... "name": "John",
... "age": 30,
... "city": "Madrid"
... }
>>>
>>> for key in user_data:
... print(f"Clave: {key}")
Clave: name
Clave: age
Clave: cityIterar sobre valores con .values()
>>> prices = {
... "laptop": 800,
... "phone": 500,
... "tablet": 300
... }
>>>
>>> total = 0
>>> for price in prices.values():
... total += price
>>>
>>> print(f"Total: ${total}")
Total: $1600Iterar sobre pares clave-valor con .items()
>>> inventory = {
... "apples": 50,
... "bananas": 30,
... "oranges": 25
... }
>>>
>>> for product, quantity in inventory.items():
... print(f"{product.capitalize()}: {quantity} unidades")
Apples: 50 unidades
Bananas: 30 unidades
Oranges: 25 unidadesCaso real – Procesar inventario con alertas
Vamos a crear un sistema que revisa el inventario de una tienda y alerta sobre productos con stock bajo. Esto es típico en sistemas de gestión de inventario:
>>> inventory = {
... "laptop": 5,
... "mouse": 50,
... "keyboard": 3,
... "monitor": 15
... }
>>>
>>> low_stock_threshold = 10
>>> low_stock_items = []
>>>
>>> print("Estado del inventario:")
>>> for product, stock in inventory.items():
... status = "⚠️ BAJO" if stock < low_stock_threshold else "✓ OK"
... print(f"{product}: {stock} unidades - {status}")
...
... if stock < low_stock_threshold:
... low_stock_items.append(product)
>>>
>>> if low_stock_items:
... print(f"\nAlerta: Reponer {', '.join(low_stock_items)}")
Estado del inventario:
laptop: 5 unidades - ⚠️ BAJO
mouse: 50 unidades - ✓ OK
keyboard: 3 unidades - ⚠️ BAJO
monitor: 15 unidades - ✓ OK
Alerta: Reponer laptop, keyboardCasos de uso reales de bucles
Caso 1: Procesamiento de archivos línea por línea
Cuando trabajas con archivos de log, necesitas encontrar y contar errores rápidamente. Este patrón es muy común en análisis de logs y debugging de aplicaciones:
>>> # Simulación de lectura de archivo
>>> log_lines = [
... "ERROR: Connection failed",
... "INFO: Server started",
... "ERROR: Database timeout",
... "INFO: Request processed",
... "ERROR: Invalid credentials"
... ]
>>>
>>> error_count = 0
>>> errors = []
>>>
>>> for line_number, line in enumerate(log_lines, start=1):
... if "ERROR" in line:
... error_count += 1
... errors.append((line_number, line))
... print(f"Línea {line_number}: {line}")
Línea 1: ERROR: Connection failed
Línea 3: ERROR: Database timeout
Línea 5: ERROR: Invalid credentials
>>>
>>> print(f"\nTotal errores encontrados: {error_count}")
Total errores encontrados: 3Caso 2: Validación de formulario con retry
En aplicaciones web, necesitas validar el input del usuario y darle múltiples oportunidades de corregirlo. Aquí creamos un validador de email con límite de intentos:
>>> def validate_email(email):
... return "@" in email and "." in email
>>>
>>> max_retries = 3
>>> attempt = 0
>>> valid_email = None
>>>
>>> while attempt < max_retries and not valid_email:
... email_input = input(f"Ingresa email (intento {attempt + 1}/{max_retries}): ")
...
... if validate_email(email_input):
... valid_email = email_input
... print(f"Email válido: {valid_email}")
... else:
... attempt += 1
... if attempt < max_retries:
... print("Email inválido. Intenta nuevamente.")
>>>
>>> if not valid_email:
... print("Máximo de intentos alcanzado")Caso 3: Sistema de descuentos progresivos
Los sistemas de e-commerce suelen tener descuentos que se acumulan según diferentes criterios. Este ejemplo muestra cómo procesar pedidos aplicando múltiples reglas de descuento:
>>> orders = [
... {"id": 1, "total": 150, "customer": "premium"},
... {"id": 2, "total": 80, "customer": "regular"},
... {"id": 3, "total": 300, "customer": "premium"},
... {"id": 4, "total": 50, "customer": "regular"}
... ]
>>>
>>> for order in orders:
... discount = 0
...
... # Descuento por tipo de cliente
... if order["customer"] == "premium":
... discount += 0.15
...
... # Descuento adicional por monto
... if order["total"] > 100:
... discount += 0.10
...
... final_price = order["total"] * (1 - discount)
... savings = order["total"] - final_price
...
... print(f"Pedido #{order['id']}")
... print(f" Cliente: {order['customer']}")
... print(f" Subtotal: ${order['total']}")
... print(f" Descuento: {discount * 100}%")
... print(f" Total: ${final_price:.2f}")
... print(f" Ahorras: ${savings:.2f}\n")
Pedido #1
Cliente: premium
Subtotal: $150
Descuento: 25.0%
Total: $112.50
Ahorras: $37.50
Pedido #2
Cliente: regular
Subtotal: $80
Descuento: 0.0%
Total: $80.00
Ahorras: $0.00
Pedido #3
Cliente: premium
Subtotal: $300
Descuento: 25.0%
Total: $225.00
Ahorras: $75.00
Pedido #4
Cliente: regular
Subtotal: $50
Descuento: 0.0%
Total: $50.00
Ahorras: $0.00Caso 4: Búsqueda y filtrado de datos
Filtrar datos de catálogos o bases de datos es una operación muy frecuente. Aquí buscamos productos específicos que cumplan múltiples criterios:
>>> products = [
... {"name": "Laptop", "price": 800, "category": "electronics", "stock": 5},
... {"name": "Mouse", "price": 25, "category": "electronics", "stock": 50},
... {"name": "Desk", "price": 200, "category": "furniture", "stock": 10},
... {"name": "Chair", "price": 150, "category": "furniture", "stock": 0},
... {"name": "Monitor", "price": 300, "category": "electronics", "stock": 15}
... ]
>>>
>>> # Buscar productos de electrónica con stock disponible
>>> search_category = "electronics"
>>> available_products = []
>>>
>>> for product in products:
... if product["category"] == search_category and product["stock"] > 0:
... available_products.append(product)
>>>
>>> print(f"Productos de {search_category} disponibles:")
>>> for product in available_products:
... print(f"- {product['name']}: ${product['price']} ({product['stock']} unidades)")
Productos de electronics disponibles:
- Laptop: $800 (5 unidades)
- Mouse: $25 (50 unidades)
- Monitor: $300 (15 unidades)Errores comunes con bucles
Error 1: Bucle infinito accidental
# Incorrecto (la condición nunca cambia)
>>> counter = 0
>>> while counter < 5:
... print(counter)
... # Olvidaste incrementar counter!
# Correcto
>>> counter = 0
>>> while counter < 5:
... print(counter)
... counter += 1Error 2: Modificar lista mientras iteras
# Incorrecto (puede causar comportamiento inesperado)
>>> numbers = [1, 2, 3, 4, 5]
>>> for num in numbers:
... if num % 2 == 0:
... numbers.remove(num) # ¡No hagas esto!
# Correcto (itera sobre una copia)
>>> numbers = [1, 2, 3, 4, 5]
>>> for num in numbers[:]: # [:] crea una copia
... if num % 2 == 0:
... numbers.remove(num)
>>> numbers
[1, 3, 5]
# Mejor aún (usa list comprehension)
>>> numbers = [1, 2, 3, 4, 5]
>>> numbers = [num for num in numbers if num % 2 != 0]
>>> numbers
[1, 3, 5]Error 3: Usar range con longitud incorrecta
# Incorrecto (IndexError)
>>> items = ["a", "b", "c"]
>>> for i in range(len(items) + 1):
... print(items[i])
a
b
c
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
IndexError: list index out of range
# Correcto
>>> items = ["a", "b", "c"]
>>> for i in range(len(items)):
... print(items[i])
a
b
c
# Mejor (pythónico)
>>> for item in items:
... print(item)Error 4: No inicializar acumuladores
# Incorrecto
>>> numbers = [1, 2, 3, 4, 5]
>>> for num in numbers:
... total += num # NameError: total no está definido
# Correcto
>>> numbers = [1, 2, 3, 4, 5]
>>> total = 0 # Inicializar antes del bucle
>>> for num in numbers:
... total += num
>>> total
15Error 5: Confundir break y continue
>>> # break sale del bucle completamente
>>> for i in range(5):
... if i == 3:
... break
... print(i)
0
1
2
>>> # continue salta a la siguiente iteración
>>> for i in range(5):
... if i == 3:
... continue
... print(i)
0
1
2
4Error 6: Índice fuera de rango en while
# Incorrecto
>>> items = ["a", "b", "c"]
>>> i = 0
>>> while i <= len(items): # <= es incorrecto
... print(items[i])
... i += 1
a
b
c
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
IndexError: list index out of range
# Correcto
>>> items = ["a", "b", "c"]
>>> i = 0
>>> while i < len(items): # < es correcto
... print(items[i])
... i += 1
a
b
cOptimización de bucles: mejores prácticas
1. Evita operaciones costosas dentro del bucle
Cada operación dentro de un bucle se ejecuta múltiples veces. Si calculas algo que no cambia en cada iteración, hazlo una sola vez antes del bucle para mejorar significativamente el rendimiento:
# Malo (calcula len() en cada iteración)
>>> items = list(range(1000))
>>> i = 0
>>> while i < len(items):
... process(items[i])
... i += 1
# Mejor (calcula len() una sola vez)
>>> items = list(range(1000))
>>> length = len(items)
>>> i = 0
>>> while i < length:
... process(items[i])
... i += 1
# Mejor aún (usa for, más pythónico)
>>> items = list(range(1000))
>>> for item in items:
... process(item)2. Usa comprensiones cuando sea apropiado
Las list comprehensions están optimizadas internamente en Python y son más rápidas que bucles for tradicionales para operaciones simples:
# Menos eficiente
>>> squares = []
>>> for i in range(100):
... squares.append(i ** 2)
# Más eficiente
>>> squares = [i ** 2 for i in range(100)]3. Break temprano cuando sea posible
Si estás buscando algo en una colección, sal del bucle tan pronto lo encuentres. No tiene sentido seguir iterando si ya tienes lo que necesitas:
# Menos eficiente (sigue iterando innecesariamente)
>>> found = None
>>> for item in large_list:
... if item == target:
... found = item
# Más eficiente (sale en cuanto encuentra)
>>> found = None
>>> for item in large_list:
... if item == target:
... found = item
... break4. Considera usar funciones built-in
Python tiene funciones optimizadas en C que son mucho más rápidas que escribir bucles manualmente. Usa sum(), max(), min(), any(), all() cuando sea posible:
# Menos eficiente
>>> numbers = [1, 2, 3, 4, 5]
>>> total = 0
>>> for num in numbers:
... total += num
# Más eficiente (optimizado en C)
>>> numbers = [1, 2, 3, 4, 5]
>>> total = sum(numbers)5. Evita concatenación de strings en bucles
Concatenar strings con += crea un nuevo objeto string en cada iteración, lo cual es muy ineficiente. Usa join() para unir múltiples strings:
# Muy ineficiente (crea nuevo string en cada iteración)
>>> result = ""
>>> for i in range(1000):
... result += str(i)
# Mucho más eficiente
>>> result = "".join(str(i) for i in range(1000))Puntos clave para recordar
Los bucles son fundamentales para automatizar tareas repetitivas y procesar colecciones de datos. Dominar for y while te permite escribir código más eficiente y elegante.
Pepitas de conocimiento
- for para iterables conocidos – Usa
forcuando sepas sobre qué iterar - while para condiciones dinámicas – Usa
whilecuando la condición de parada no esté clara - range() genera secuencias – Perfecto para contadores y rangos numéricos
- enumerate() da índice + valor – No necesitas contadores manuales
- break sale, continue salta – Controla el flujo dentro del bucle
- else después de bucles – Se ejecuta si NO se usó break
- List comprehensions son pythónicas – Pero solo para casos simples
- Evita modificar durante iteración – Itera sobre copias si necesitas modificar
- Cuidado con bucles infinitos – Asegura que la condición eventually cambie
- Inicializa acumuladores – Siempre inicializa variables antes del bucle
- while True con break – Útil para menús y servicios
- Bucles anidados = O(n²) – Ten cuidado con el rendimiento
Próximos pasos
Ahora que dominas los bucles y las condicionales, tienes todas las herramientas para controlar el flujo de ejecución de tus programas. El siguiente paso es aprender a manejar errores y excepciones para hacer tu código más robusto.
Siguiente paso: Manejo de excepciones en Python
Ya sabes controlar el flujo con condicionales y bucles. Ahora aprende a manejar errores como un profesional:
Try-except y excepciones en Python – Guía completa
¿Te ha gustado este artículo? Compártelo con otros pythonistas que estén aprendiendo a programar.
Déjanos un comentario con tus dudas sobre bucles o comparte los casos de uso más interesantes que hayas implementado.
Para profundizar más con patrones avanzados de bucles, optimización de rendimiento y técnicas profesionales, no te pierdas Python a fondo.
