Saltar al contenido
IDE libre

Fundamentos

El bucle while en Python: repetición con prueba al comienzo

Aprende el bucle while: las cuatro piezas, los patrones de contador, centinela y bandera, las condiciones compuestas y los errores de bucles infinitos.

Por Prof. Rodrigo Faustino · Actualizado el · 14 min de lectura

Métricas de este artículo

Palabras
2747
Caracteres
14.900
Tiempo de lectura
~14 min

El while repite un bloque de código mientras una condición sea verdadera, y la prueba ocurre antes de cada vuelta, incluida la primera. Por eso el bloque puede correr muchas veces, una vez o ninguna. Para que el bucle termine, algo dentro de él necesita cambiar el resultado de la prueba. Cuando eso ocurre, el programa sale del bloque y continúa en la primera línea sin sangría; cuando no ocurre, el bucle corre para siempre.

El artículo anterior mostró por qué existen los bucles y qué preguntas responde todo bucle. Este está dedicado al while: las cuatro piezas que lo forman, los tres patrones que resuelven la mayor parte de los problemas, las condiciones con and y not, el or que genera bucles infinitos, el while dentro de otro y el uso en la ESP32.

Las cuatro piezas

A la izquierda, un código de cinco líneas numeradas: i igual a 1 (1, valor inicial), while i menor o igual a 5 (2, prueba), print(i) (3, cuerpo), i más igual a 1 (4, actualización) y print fin (5, después). A la derecha, una leyenda explica cada pieza. Abajo, el orden de ejecución: 1, después 2, 3 y 4 cinco veces, después 2 y 5. Una franja avisa que la prueba viene antes del cuerpo, así que el cuerpo puede correr cero veces.
Las cuatro piezas del while y el orden en que Python las ejecuta.

Un while bien escrito tiene cuatro piezas, y la figura las numera en el orden en que Python las ejecuta:

i = 1
while i <= 5:
    print("2 x", i, "=", 2 * i)
    i += 1
print("fin")

La salida es la tabla del 2 hasta el quinto término, de 2 x 1 = 2 a 2 x 5 = 10, y después fin. Las piezas son:

  1. El valor inicial, i = 1, que queda antes del bucle y crea la variable que la prueba va a mirar.
  2. La prueba, i <= 5, que Python evalúa antes de cada vuelta. Si da True, entra al bloque; si da False, salta a después de él.
  3. El cuerpo, el print, que es el trabajo repetido.
  4. La actualización, i += 1, que cambia la variable para que la prueba, en algún momento, dé False.

La pieza 5 de la figura, el print("fin") sin sangría, no es del bucle. Corre una vez, cuando la prueba falla. Quien aprende el while suele equivocar la posición de una de estas piezas: el valor inicial dentro del bucle, la actualización fuera de él, o la prueba que no mira la variable que cambia.

El bucle que no corre ninguna vez

Como la prueba viene antes del cuerpo, un while cuya condición ya empieza falsa no ejecuta el bloque:

n = 0
while n > 0:
    print("nunca aparece")
    n = n - 1
print("el bucle no corrió, n vale", n)

La salida es solo el bucle no corrió, n vale 0. Esto es una característica útil, no un defecto: un programa que suma los valores escritos y recibe cero de entrada debe sumar nada y responder 0, sin necesidad de un if especial. El while con prueba al comienzo trata ese caso gratis. Existe otro tipo de bucle, que corre el cuerpo antes de probar, y Python no tiene una palabra propia para él. El artículo sobre el "hacer-mientras" muestra cómo simularlo.

FastTeacherPara profesores

Del programa al semestre planificado

  • Plan de enseñanza y calendario montados solos
  • Diario de clases listo para pegar en el SIGA
  • Diapositivas y listas de ejercicios con solucionario
Conocer FastTeacher

Versión Community gratis · Windows

Tres patrones que resuelven casi todo

Tres tarjetas lado a lado con un trozo de código cada una. El patrón contador usa i igual a 1, while i menor o igual a 5 e i más igual a 1, y sirve cuando se sabe cuántas vueltas. El patrón centinela lee n con input, repite mientras n sea distinto de 0 y lee de nuevo al final del bloque, y sirve cuando el usuario decide cuándo parar. El patrón bandera usa ligado igual a True, while ligado y cambia ligado a False dentro de un if, y sirve cuando un estado decide. Una franja recuerda que la línea que actualiza queda dentro del bucle.
Tres patrones de while: contador, centinela y bandera.

La mayoría de los while que se escriben al comienzo caen en uno de estos patrones. Reconocer el patrón ayuda a escribir el bucle sin ensayo y error.

El contador

Cuando se sabe cuántas vueltas dar, una variable cuenta hasta el límite. Es el patrón de la tabla de arriba: valor inicial, prueba contra el límite y += 1 al final del bloque. El contador puede crecer, disminuir (n -= 1) o avanzar de dos en dos (i += 2), y la prueba usa <, <=, > o >= según el sentido. Para este patrón, el for con range() suele ser más corto, y es el tema del próximo artículo de la serie.

El centinela

Cuando es el usuario quien decide cuándo parar, el programa no sabe de antemano cuántas vueltas serán necesarias. Un valor acordado, el centinela, avisa el final. El ejemplo calcula el promedio de notas, y el -1 cierra la lista:

soma = 0
contador = 0
nota = float(input("Nota (-1 para parar): "))
while nota != -1:
    soma = soma + nota
    contador = contador + 1
    nota = float(input("Nota (-1 para parar): "))
if contador > 0:
    print("promedio", soma / contador)
else:
    print("ninguna nota")

Con las entradas 8, 6.5, 9 y -1, la última línea de la salida es promedio 7.8333336. El Python del computador mostraría 7.833333333333333, la misma cuenta con el float de 64 bits (el simulador usa 32 bits, como la placa). Si la primera nota escrita ya es -1, el bucle no corre, el contador queda en 0 y el programa imprime ninguna nota. El if contador > 0 existe por eso: sin él, la división soma / contador sería una división por cero. El desafío Promedio de N usa una variación: el primer número leído dice cuántos valores vendrán después, y el bucle es un contador.

Fíjate en la lectura, que aparece dos veces. La primera, antes del bucle, le da a la prueba el valor con el que comparar. La segunda, en la última línea del bloque, es la actualización del patrón: es lo que cambia en cada vuelta. Quien escribe solo la primera lectura arma un bucle que lee una vez y repite para siempre el mismo valor.

La bandera

A veces el bucle depende de un estado del programa, y no de un número. Una variable booleana, la bandera, guarda ese estado y pasa a False cuando la repetición debe terminar:

carga = 100
ligado = True
while ligado:
    carga = carga - 30
    print("carga", carga)
    if carga <= 20:
        ligado = False
print("apagado con", carga)

La salida es carga 70, carga 40, carga 10 y apagado con 10. El while ligado: no necesita la comparación, porque ligado ya es un booleano. Quien decide parar es el if dentro del cuerpo, y nota que la vuelta en que la carga llega a 10 termina normalmente: la prueba solo se hace de nuevo al comienzo de la vuelta siguiente. Este patrón aparece en juegos (la partida continúa mientras el jugador tenga vidas), en menús (el menú se repite mientras el usuario no elija salir) y en programas de placa (el aparato funciona mientras no haya error).

Una condición que consume el valor

Una cuarta forma es el bucle en que la propia variable de la prueba se va gastando. La cuenta de dígitos de un número es el ejemplo clásico, y usa la división entera y el resto vistos en el artículo sobre operadores aritméticos:

n = 4821
digitos = 0
soma = 0
while n > 0:
    soma = soma + n % 10
    n = n // 10
    digitos = digitos + 1
print(digitos, soma, n)

La salida es 4 15 0. El n % 10 toma el último dígito, y el n // 10 lo descarta. En cada vuelta el número se encoge: 4821, 482, 48, 4, 0. Cuando llega a 0, la prueba n > 0 falla. El programa contó 4 dígitos, sumó 4 + 8 + 2 + 1 = 15 y dejó n en cero, lo que muestra que el bucle destruye el valor original. Si el número necesita usarse después, guarda una copia en una variable antes del bucle.

Condiciones compuestas: and, not y la cuenta de intentos

La condición del while es una expresión booleana como las del if, y acepta and, or y not. Un uso muy común es combinar "todavía hay intentos" con "todavía no acertó", y el ejemplo de la contraseña muestra los dos:

tentativas = 0
acertou = False
while tentativas < 3 and not acertou:
    senha = input("Contraseña: ")
    tentativas = tentativas + 1
    if senha == "1234":
        acertou = True
    else:
        print("contraseña incorrecta")
if acertou:
    print("acceso permitido")
else:
    print("bloqueado")

Con las entradas 1111 y 1234, el programa muestra contraseña incorrecta y después acceso permitido. Si las tres contraseñas son erróneas (1111, 2222 y 3333), muestra contraseña incorrecta tres veces y termina con bloqueado. El bucle tiene dos razones para parar, y cada una es una mitad de la condición: se acabaron los intentos o el usuario acertó. El and exige que las dos sigan verdaderas para repetir. Después del bucle, el if acertou descubre cuál de las dos razones cerró la repetición, un truco que sirve para cualquier bucle con dos salidas. El desafío Contraseña 1234 es la versión más simple de esta idea, sin límite de intentos: repite la lectura hasta la contraseña correcta.

FastMindAsistente de IA local

La IA que recuerda tu vida y vive en tu ordenador

  • Memoria a largo plazo con la fuente de cada respuesta
  • Funciona sin conexión: tus datos se quedan en tu PC
  • Lee PDF, diapositivas, fotos y grabaciones de reuniones
Descargar gratis para Windows

Plan Esencial gratis para siempre

El error del or

Una tabla de verdad con las respuestas s, n y x. Las columnas muestran resp distinto de s, resp distinto de n, el resultado con or y el resultado con and. Con or, el resultado es True en las tres filas, así que el bucle nunca sale. Con and, el resultado es False para s y para n y True para x. Abajo, el bucle equivocado con or se muestra en rojo y el bucle correcto con and, o con not in, en verde.
Con or la condición queda siempre verdadera y el bucle nunca termina; con and el bucle repite solo para respuestas inválidas.

La pregunta "repite mientras la respuesta no sea s ni n" es una trampa de lógica, y casi todos la escriben mal al menos una vez, porque la frase en español tiene "ni" y el código pide and. La tabla de la figura muestra la cuenta:

for resp in ("s", "n", "x"):
    print(resp, resp != "s" or resp != "n", resp != "s" and resp != "n", resp not in ("s", "n"))

La salida es s True False False, n True False False y x True True True. La segunda columna, la del or, da True en las tres filas. Quien escribe s pasa la prueba resp != "n", y quien escribe n pasa la prueba resp != "s", así que ninguna respuesta hace que el bucle se detenga, ni siquiera la respuesta correcta. El and y el not in dan False para s y para n, y True solo para la respuesta inválida. La versión correcta, con el mensaje de error y la nueva lectura dentro del bucle, es esta:

resp = input("Continuar (s/n)? ")
while resp != "s" and resp != "n":
    print("Responde s o n")
    resp = input("Continuar (s/n)? ")
print("respuesta", resp)

Con las entradas x, q y s, la salida pide la respuesta de nuevo dos veces y termina con respuesta s. Es la misma situación de las tablas de verdad: cuando la condición parece correcta pero el programa se comporta mal, arma la tabla con los valores posibles. Las leyes de De Morgan, tratadas en ese artículo, explican por qué "no s y no n" es lo mismo que "no (s o n)".

Un while dentro de otro

El cuerpo de un while puede contener otro while. El bucle de adentro corre completo en cada vuelta del de afuera, y el resultado es una cuadrícula:

i = 1
while i <= 3:
    j = 1
    while j <= 3:
        print(i * j, end=" ")
        j += 1
    print()
    i += 1

La salida es la tabla de 1 a 3 en tres líneas: 1 2 3, 2 4 6 y 3 6 9. El end=" " cambia el salto de línea del print por un espacio, para que los números queden lado a lado, y el print() vacío, en la sangría del bucle de afuera, corta la línea al final de cada fila. Fíjate en que el j = 1 queda dentro del bucle de afuera: necesita volver a 1 en cada fila. Olvidar esto, o poner el j = 1 antes de los dos bucles, es el defecto clásico, porque en la segunda fila el j ya vale 4 y el bucle de adentro no corre ninguna vez.

Qué cambia en la ESP32

El while de MicroPython es el mismo del Python del computador. Dos usos aparecen todo el tiempo en programas de placa. El primero es el bucle principal, el while True: del main.py, que lee sensores, decide y actúa hasta que se apague la placa. Necesita una pausa con time.sleep o time.sleep_ms dentro del cuerpo, si no corre lo más rápido que el procesador deje. El artículo sobre programar sin colgarse muestra cómo hacer varias tareas dentro de él.

El segundo es esperar algo con límite de tiempo, una espera con timeout. La prueba compara el tiempo que pasó con un límite:

import time
inicio = time.ticks_ms()
voltas = 0
while time.ticks_diff(time.ticks_ms(), inicio) < 200:
    voltas = voltas + 1
    time.sleep_ms(50)
print("al menos 3 vueltas:", voltas >= 3)

La salida es al menos 3 vueltas: True. La función time.ticks_ms() devuelve un contador de milisegundos, y time.ticks_diff calcula la diferencia entre dos valores sin confundirse cuando el contador da la vuelta, lo que el - simple no garantiza, como explica el artículo sobre ticks. El bucle repite mientras hayan pasado menos de 200 ms. El programa imprime solo si hubo al menos tres vueltas, y no el número exacto, porque cambia de una ejecución a otra, y en la placa también depende de la velocidad de la lectura. Es la base de esperas como "aguarda la respuesta del sensor hasta por dos segundos". Un bucle de espera siempre necesita una salida por tiempo, para que la placa no quede atrapada en un sensor que nunca responde.

Los bucles con float piden el cuidado del artículo anterior: comparar con == o != un valor acumulado de 0,1 en 0,1 puede no dar nunca resultado, y una cuenta de vueltas entera como tope es la defensa más simple.

En el aula: dónde suele tropezar el while

Los casos de abajo se repiten en los grupos, y los de bucle infinito son los que más llaman al profesor. En todos el programa corre, y lo que falla es el comportamiento.

La actualización fuera del bucle

La línea de actualización sale de la sangría y la prueba nunca cambia:

i = 1
voltas = 0
while i <= 3 and voltas < 5:
    print("i vale", i)
    voltas += 1
i = i + 1
print("vueltas", voltas, "i", i)

La salida tiene cinco líneas i vale 1, después vueltas 5 i 2. El i = i + 1 está en el margen, después del bucle, así que corre una sola vez, al final. El i queda en 1 durante todo el bucle. Sin el tope del voltas, el programa imprimiría i vale 1 para siempre. El tope es una buena práctica de depuración: un contador de seguridad que corta el bucle en el valor esperado más un margen.

El signo igual en la prueba

El = es asignación y el == es comparación, y un while n = 0: no funciona. Los mensajes varían:

ErrorSimulador (MicroPython)Python en el computador
while n = 0:SyntaxError: invalid syntax (línea 2)SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
while n > 0 sin los dos puntosSyntaxError: invalid syntax (línea 2)SyntaxError: expected ':'
cuerpo sin sangríaSyntaxError: invalid syntax (línea 3)IndentationError: expected an indented block after 'while' statement on line 2

El simulador dice solo invalid syntax y la línea. La pista es mirar la línea indicada: el = donde debía haber ==, los dos puntos que faltan al final de la línea del while y la línea siguiente que no tiene sangría. El artículo sobre if y else trata los errores de sangría con más detalle.

La segunda lectura que no existe

En el patrón del centinela, quien lee el valor solo antes del bucle se queda con un bucle infinito: la variable de la prueba nunca cambia. Es el mismo error de la actualización olvidada, con una excusa más difícil de ver, porque el input() queda justo encima del while y da la impresión de que la lectura "ya está ahí". La pregunta de prueba es: ¿dónde, dentro del bloque, cambia el valor de nota?

Olvidar el caso de cero vueltas

El promedio sin ninguna nota, la suma de una lista vacía, la contraseña de un usuario que desiste antes de empezar. Si el programa divide por el contador, el if contador > 0 del ejemplo del promedio existe para eso. La prueba que vale la pena hacer en todo while es la primera vuelta ya falsa.

El or en lugar del and

El error de la figura, con la tabla de verdad. La frase en español "mientras no sea s ni n" es un and, y el or produce un bucle que nunca termina, y que pasa sin ningún aviso.

El j que no vuelve al comienzo

En bucles anidados, la variable del bucle de adentro necesita reiniciarse en cada vuelta del de afuera. El síntoma es la segunda fila de la cuadrícula vacía, sin ningún error.

Ejercicio: adivina el número

El programa sortea (aquí, fija) un número secreto y el jugador prueba hasta acertar. En cada intento errado, el programa dice si el secreto es mayor o menor, y al final informa cuántos intentos fueron necesarios. Reúne el centinela (el acierto es el final), un if dentro del bucle y un contador.

segredo = 65
palpite = int(input("Intento: "))
tentativas = 1
while palpite != segredo:
    if palpite < segredo:
        print("mayor")
    else:
        print("menor")
    palpite = int(input("Intento: "))
    tentativas = tentativas + 1
print("acertó en", tentativas, "intentos")

Con los intentos 50, 75, 62, 68 y 65, la salida alterna mayor, menor, mayor, menor y termina con acertó en 5 intentos. El contador empieza en 1 porque el primer intento se lee antes del bucle, y cada lectura dentro del bucle suma un intento más. Para ampliar, agrega un límite de intentos a la condición, while palpite != segredo and tentativas < 7, y un mensaje de derrota después del bucle, como en el ejemplo de la contraseña.

Preguntas frecuentes

¿Cuál es la diferencia entre while e if?

El if prueba una vez y sigue adelante. El while vuelve a la prueba después de cada ejecución del bloque y solo sigue cuando falla.

¿Cuándo usar while y cuándo usar for?

Usa for cuando ya se sabe qué recorrer (los números de 1 a 10, los elementos de un grupo). Usa while cuando el final depende de algo que solo aparece corriendo, como una respuesta del usuario, una lectura de sensor o una condición que cambia sola.

¿Qué es while True?

Es un bucle cuya condición nunca queda falsa. Termina por un break dentro del cuerpo o cuando se interrumpe el programa. Es la estructura del bucle principal de la ESP32, y el artículo sobre break y continue muestra los otros usos.

¿El while puede tener else?

Puede, y el bloque del else corre cuando la prueba falla, pero no cuando el bucle se interrumpe por break. El tema es del artículo sobre break, continue y el else de los bucles.

¿Cómo descubro por qué mi bucle no termina?

Pon un print con la variable de la prueba dentro del bucle y sigue los valores, como en la tabla de seguimiento del artículo anterior. Si el valor no cambia, falta la actualización. Si cambia pero nunca llega al límite, el sentido está mal o la condición está mal escrita.

Para continuar

La ruta Lógica con Python tiene los desafíos de repetición. El Hasta cero es el centinela más simple, la Suma dinámica suma valores con el centinela, la Contraseña 1234 repite la lectura hasta acertar, y el Promedio de N combina contador y acumulador. Para la base, relee Por qué repetir.

El próximo tema es el bucle for y la función range(): la forma corta de repetir un número conocido de veces, sin escribir las cuatro piezas a mano.

Para practicar en PyPlaca

Rutas

Lecciones

Fichas de componentes

FastMindAsistente de IA local

La IA que recuerda tu vida y vive en tu ordenador

  • Memoria a largo plazo con la fuente de cada respuesta
  • Funciona sin conexión: tus datos se quedan en tu PC
  • Lee PDF, diapositivas, fotos y grabaciones de reuniones
Descargar gratis para Windows

Plan Esencial gratis para siempre

FastTeacherPara profesores

Del programa al semestre planificado

  • Plan de enseñanza y calendario montados solos
  • Diario de clases listo para pegar en el SIGA
  • Diapositivas y listas de ejercicios con solucionario
Conocer FastTeacher

Versión Community gratis · Windows

FastMindAsistente de IA local

La IA que recuerda tu vida y vive en tu ordenador

  • Memoria a largo plazo con la fuente de cada respuesta
  • Funciona sin conexión: tus datos se quedan en tu PC
  • Lee PDF, diapositivas, fotos y grabaciones de reuniones
Descargar gratis para Windows

Plan Esencial gratis para siempre