El bucle while repite un bloque de código mientras una condición sea verdadera. Es especialmente útil cuando no sabes de antemano cuántas veces debe repetirse una tarea: validar una entrada, mantener un menú activo, esperar una condición, procesar datos hasta encontrar un marcador o ejecutar un juego hasta que termine la partida.
Antes de comenzar, conviene repasar los bucles en Python, la función input(), las funciones, los booleanos y el manejo de excepciones. Como referencias externas, consulta la referencia oficial de la sentencia while y el tutorial oficial de control de flujo.
La estructura básica
contador = 1
while contador <= 5:
print(contador)
contador += 1
Python evalúa la condición antes de cada iteración. Mientras contador <= 5 sea verdadero, ejecuta el bloque. La actualización contador += 1 es fundamental: sin ella, la condición nunca cambiaría y el bucle sería infinito.
Cómo funciona paso a paso
En la primera vuelta, contador vale uno. Python comprueba la condición, imprime el valor y suma uno. El proceso continúa hasta que contador llega a seis. En ese momento la condición es falsa y la ejecución continúa después del bloque.
Cuándo usar while
Usa while cuando la repetición dependa de una condición dinámica. Por ejemplo:
- Preguntar hasta recibir una respuesta válida.
- Mantener un menú hasta que el usuario elija salir.
- Repetir una partida mientras queden vidas.
- Procesar elementos hasta encontrar un valor centinela.
- Reintentar una operación con un límite controlado.
Cuando conoces la cantidad exacta de repeticiones o recorres una colección, normalmente un for es más claro.
Validar una entrada
while True:
texto = input("Edad: ").strip()
try:
edad = int(texto)
except ValueError:
print("Debes escribir un número entero.")
continue
if edad < 0:
print("La edad no puede ser negativa.")
continue
break
print(f"Edad válida: {edad}")
while True crea un bucle deliberadamente infinito. La salida se controla con break cuando la entrada cumple todas las reglas. continue salta directamente a la siguiente iteración.
Menú interactivo
def mostrar_menu():
print("1. Añadir tarea")
print("2. Listar tareas")
print("0. Salir")
tareas = []
while True:
mostrar_menu()
opcion = input("Opción: ").strip()
if opcion == "0":
print("Hasta pronto")
break
elif opcion == "1":
tarea = input("Nueva tarea: ").strip()
if tarea:
tareas.append(tarea)
elif opcion == "2":
for indice, tarea in enumerate(tareas, start=1):
print(f"{indice}. {tarea}")
else:
print("Opción inválida")
El menú continúa hasta que el usuario elige cero. La lógica principal puede dividirse en funciones para facilitar pruebas y mantenimiento.
Usar una condición en lugar de while True
activo = True
while activo:
comando = input("Comando: ").strip().lower()
if comando == "salir":
activo = False
else:
print(f"Ejecutando: {comando}")
Esta variante expresa el estado mediante una variable booleana. Puede ser más clara cuando otras partes del programa también necesitan cambiar ese estado.
Contadores y acumuladores
contador = 0
total = 0
while contador < 5:
numero = float(input("Número: "))
total += numero
contador += 1
promedio = total / contador
print(f"Promedio: {promedio:.2f}")
El contador registra cuántos valores se procesaron y el acumulador conserva la suma. Si el número de entradas está fijado, un for con range probablemente resulte más directo, pero este ejemplo muestra el patrón.
Valores centinela
Un centinela indica que la entrada terminó:
total = 0.0
cantidad = 0
while True:
texto = input("Importe o 'fin': ").strip().lower()
if texto == "fin":
break
try:
importe = float(texto.replace(",", "."))
except ValueError:
print("Importe inválido")
continue
total += importe
cantidad += 1
print(f"Elementos: {cantidad}")
print(f"Total: {total:.2f}")
El programa no sabe cuántos importes recibirá. La palabra fin termina el proceso.
break
break termina el bucle más cercano:
numero = 2
while numero < 100:
if numero == 16:
break
print(numero)
numero *= 2
En bucles anidados, break solo sale del bloque interior. Para abandonar varios niveles, suele ser mejor extraer la lógica a una función y utilizar return.
continue
numero = 0
while numero < 10:
numero += 1
if numero % 2 != 0:
continue
print(numero)
Los números impares saltan la impresión. Actualizar el contador antes de continue evita que el programa quede atrapado en el mismo valor.
La cláusula else
objetivo = 7
numero = 1
while numero <= 10:
if numero == objetivo:
print("Encontrado")
break
numero += 1
else:
print("No se encontró el objetivo")
El bloque else se ejecuta cuando el bucle termina porque la condición se vuelve falsa. No se ejecuta si hubo un break. Puede ser útil en búsquedas, aunque no debe usarse si hace la lógica más difícil de comprender.
Evitar bucles infinitos accidentales
# Incorrecto
contador = 0
while contador < 5:
print(contador)
La variable nunca cambia. Para prevenir este problema, identifica qué elemento debe modificar la condición y asegúrate de que todas las rutas posibles lo actualicen.
También puedes añadir un límite de seguridad:
intentos = 0
max_intentos = 3
while intentos < max_intentos:
intentos += 1
if realizar_operacion():
break
else:
print("No fue posible completar la operación")
Reintentos con pausa
import time
intento = 0
max_intentos = 4
while intento < max_intentos:
intento += 1
try:
resultado = consultar_servicio()
except TimeoutError:
if intento == max_intentos:
raise
time.sleep(2)
else:
break
Una pausa evita reintentos inmediatos, pero no bloquees innecesariamente una interfaz gráfica o un servidor. En aplicaciones concurrentes, utiliza mecanismos asincrónicos o tareas en segundo plano.
Esperar una condición
import time
from pathlib import Path
ruta = Path("resultado.txt")
limite = 30
inicio = time.monotonic()
while not ruta.exists():
if time.monotonic() - inicio > limite:
raise TimeoutError("El archivo no apareció")
time.sleep(0.5)
Siempre incorpora un tiempo máximo. Esperar para siempre puede dejar un proceso bloqueado sin explicación.
while con listas
cola = ["tarea-1", "tarea-2", "tarea-3"]
while cola:
tarea = cola.pop(0)
print(f"Procesando {tarea}")
Una lista vacía es falsa. Sin embargo, eliminar el primer elemento de una lista repetidamente puede ser ineficiente. Para una cola real, utiliza collections.deque y popleft().
Una cola con deque
from collections import deque
cola = deque(["A", "B", "C"])
while cola:
elemento = cola.popleft()
print(elemento)
Este patrón procesa elementos hasta vaciar la colección.
Bucles anidados
fila = 1
while fila <= 3:
columna = 1
while columna <= 3:
print(f"({fila}, {columna})")
columna += 1
fila += 1
Reinicia la variable interior en cada vuelta exterior. Si la estructura se vuelve profunda, considera funciones o un enfoque diferente.
Crear un juego sencillo
import random
secreto = random.randint(1, 20)
vidas = 5
while vidas > 0:
propuesta = int(input("Adivina el número: "))
if propuesta == secreto:
print("¡Correcto!")
break
vidas -= 1
pista = "mayor" if propuesta < secreto else "menor"
print(f"El número secreto es {pista}. Vidas: {vidas}")
else:
print(f"Perdiste. Era {secreto}")
La condición representa el recurso restante. Si no hay victoria, el else muestra la derrota.
Separar lógica de entrada
def contar_hasta(limite):
valores = []
actual = 1
while actual <= limite:
valores.append(actual)
actual += 1
return valores
Esta función puede probarse sin terminal:
assert contar_hasta(3) == [1, 2, 3]
assert contar_hasta(0) == []
Pruebas de bucles
Los tests deben cubrir la condición inicial falsa, una sola iteración, varias iteraciones, salida con break y el límite máximo. Evita tests que esperen durante segundos reales; inyecta una función de reloj o reduce la espera mediante mocks.
while frente a for
# Mejor con for
for numero in range(5):
print(numero)
# Natural con while
respuesta = ""
while respuesta not in {"s", "n"}:
respuesta = input("¿Continuar? (s/n): ").strip().lower()
Elige la estructura que exprese mejor la intención. Un while con contador puede funcionar, pero no siempre es la opción más legible.
Errores frecuentes
Los problemas más comunes son olvidar actualizar la condición, colocar continue antes de la actualización, no establecer un límite para reintentos, usar while True sin una salida clara y bloquear una interfaz con time.sleep. También es frecuente mezclar entrada, lógica y almacenamiento en un único bloque enorme.
Buenas prácticas
Define una condición comprensible, limita las operaciones externas, registra fallos importantes y extrae el cuerpo a funciones cuando crezca. Si el bucle depende de múltiples banderas difíciles de seguir, quizá necesites una máquina de estados o una estructura diferente.
Conclusión
El bucle while es ideal para repeticiones controladas por condiciones: validación, menús, reintentos, colas y juegos. Asegúrate de que la condición pueda cambiar, utiliza break y continue con intención y añade límites a cualquier espera. Cuando conoces el número de repeticiones o recorres una colección, compara la solución con un for. La estructura correcta debe hacer evidente por qué y cuándo termina el ciclo.






