Saltar a contenido

1.5 · Bucles

Objetivos. Al terminar este capítulo podrás: repetir código con for y while; controlar el flujo con break, continue y la cláusula else; anidar bucles; y usar el operador walrus := para simplificar condiciones.

Evidencia de logro. Escribirás programas que recorren colecciones y repiten hasta cumplir una condición (factorial, tabla de multiplicar, menú), controlando cuándo salir.

Contexto y motivación

Muchos programas repiten una misma operación: recorrer una lista de pedidos, sumar ventas o mostrar un menú hasta que el usuario salga. Los bucles permiten expresar esa repetición sin copiar y pegar código y funcionan también cuando el número de datos cambia.

Python ofrece dos bucles principales: for (recorre una secuencia o colección) y while (repite mientras una condición sea verdadera). La elección depende de si tienes una colección que recorrer o una condición que determine cuándo terminar.

Vocabulario

Término Significado
Iteración Una vuelta del bucle
Iterable Objeto que se puede recorrer (list, str, range, dict…)
range Secuencia de números, muy usada con for
break Sale del bucle inmediatamente
continue Salta a la siguiente iteración
Bucle anidado Un bucle dentro de otro
Walrus := Asigna y devuelve un valor en la misma expresión

Prerrequisitos

1.4 · Condicionales (para usar if dentro del bucle) y saber manejar variables.

Ruta de estudio

El núcleo obligatorio es recorrer con for y while, usar range, acumuladores, break y continue, y evitar bucles infinitos. La cláusula else de los bucles, los bucles anidados y el operador walrus := se trabajan como ampliación guiada después de dominar esos patrones.

1. while: repetir mientras la condición sea verdadera

n = 0

while n < 3:
    print(n)
    n += 1

Salida esperada:

0
1
2

El bucle comprueba n < 3 antes de cada vuelta; si es True, ejecuta el cuerpo y vuelve a comprobar. Si olvidas n += 1, la condición nunca cambia y el bucle es infinito (lo verás en errores frecuentes).

1.1 Acumulador con while

total = 0
n = 1

while n <= 5:
    total += n
    n += 1

print(total)

Salida esperada:

15

Aquí aparecen dos patrones que usarás constantemente: un acumulador (total, que empieza en 0 y va sumando) y un contador (n, que avanza en cada vuelta). Sin n += 1 el bucle sería infinito. Si pasa, detén el programa con Ctrl+C en la terminal.

2. for: recorrer una secuencia

for i in range(5):
    print(i)

Salida esperada:

0
1
2
3
4

range(5) genera 0, 1, 2, 3, 4 (el 5 no se incluye). En cada vuelta, la variable i toma el siguiente valor. Con for no tienes que manejar un contador a mano: el bucle te da cada valor.

for i in range(2, 8, 2):   # de 2 a 7, de 2 en 2
    print(i)

Salida esperada:

2
4
6

La forma completa es range(inicio, fin, paso): empieza en inicio, avanza de paso en paso y se detiene antes de fin. El for también recorre directamente cualquier colección, como una cadena (letra a letra) o una lista de valores entre corchetes (elemento a elemento; las listas se estudian en 1.6):

for letra in "hola":
    print(letra)

Salida esperada:

h
o
l
a
precios = [12, 5, 8]
total = 0
for precio in precios:
    total += precio
print("Total:", total)

Salida esperada:

Total: 25

for es lo habitual

En cuanto tengas una colección finita, usa for. El while queda para cuando la condición no depende de una secuencia conocida (p. ej. "lee hasta vacío", "hasta que el usuario salga"). La regla mental: si sabes cuántas veces o sobre qué recorres, for; si dependes de una condición, while.

3. break y continue

break sale del bucle; continue salta a la siguiente vuelta:

for i in range(10):
    if i == 3:
        break
    print(i)

Salida esperada:

0
1
2

Al llegar a i == 3, break interrumpe y ya no imprime 4, 5…

for i in range(6):
    if i % 2 == 0:      # pares
        continue         # saltar a la siguiente
    print(i)

Salida esperada:

1
3
5

Diferencia: break termina el bucle; continue continúa con el siguiente elemento, saltándose el código de esa vuelta.

4. Ampliación: bucles anidados

Un bucle dentro de otro se ejecuta "por cada elemento del exterior, todo el interior":

for i in range(1, 4):        # filas
    for j in range(1, 4):    # columnas
        print(i * j, end=" ")
    print()                  # salto de línea al acabar cada fila

Salida esperada:

1 2 3 
2 4 6 
3 6 9 

El end=" " evita el salto de línea y el print() al final del bucle interno queda para la siguiente fila.

for i in range(1, 5):
    print("*" * i)

Salida esperada:

*
**
***
****

"*" * i repite la cadena i veces. Los bucles anidados son potentes pero costosos (piensa en "filas × columnas"); úsalos con cabeza.

5. Ampliación: la cláusula else en bucles

El else de un bucle se ejecuta si el bucle termina sin break:

for i in range(5):
    if i == 10:
        break
else:
    print("Bucle terminado sin break")

Salida esperada:

Bucle terminado sin break

Es útil para "buscar": si haces un bucle buscando algo y haces break al encontrarlo, el else te dice "no lo encontré".

Se lee casi como una búsqueda

for x in datos: + break si encuentro + else: no lo encontré. Es un patrón idiomático para comprobar si un elemento cumple una condición.

6. Aplicación práctica: factorial

n = 5
factorial = 1

for i in range(1, n + 1):
    factorial *= i

print("5! =", factorial)

Salida esperada:

5! = 120

El factorial (5! = 5×4×3×2×1) es el ejemplo canónico de acumulador. Fíjate en range(1, n + 1): va de 1 a n incluido.

7. Ampliación: el operador walrus :=

:= asigna un valor y lo devuelve a la vez. Sirve para no repetir un cálculo que usas en la condición:

datos = ["a", "b", "c"]

if (total := len(datos)) > 2:
    print(f"Hay {total} elementos")

Salida esperada:

Hay 3 elementos

Sin el walrus tendrías que escribir la asignación y la comprobación en líneas separadas. Con :=, la asignación y el uso van juntos. En un bucle es útil cuando la condición obtiene un nuevo valor y, a continuación, decide si debe procesarlo:

elementos = iter(["a", "b", "c"])

while (elemento := next(elementos, None)) is not None:
    print(elemento)

Salida esperada:

a
b
c

Para entenderlo necesitas dos funciones nuevas:

  • iter(lista) devuelve un iterador: un objeto que va entregando los elementos de uno en uno.
  • next(iterador, None) entrega el siguiente elemento y, si ya no queda ninguno, devuelve el valor por defecto que le hemos dado (None).

En cada comprobación, el while pide el siguiente elemento, lo guarda en elemento y comprueba si es None; cuando se acaban, el bucle termina. Este patrón de «leer hasta que no quede nada» lo verás de nuevo al leer ficheros o entradas del usuario. Si te resulta difícil ahora, no pasa nada: es una ampliación y un for resuelve el mismo recorrido.

Ampliación: bucle de menú (interactivo)

El while brilla en un menú: repite hasta que el usuario elija salir. Como depende de la entrada del usuario, se ejecuta en la terminal (no es reproducible solo en un cuaderno, así que aquí mostramos el patrón y lo pruebas en tu equipo):

while True:
    opcion = input("1-Listar · 2-Salir > ")
    if opcion == "2":
        print("Saliendo...")
        break
    elif opcion == "1":
        print("Listando...")
    else:
        print("Opción no válida")

El while True + break es el patrón de menú: un "bucle para siempre" que solo termina cuando una condición interna lo decide.

Errores frecuentes

  • Bucle infinito: olvidar cambiar la condición o el contador (n += 1).
  • Confundir range(5) (0-4) con range(1,6) (1-5).
  • Usar = en el if del bucle en vez de ==.
  • No entender break (termina) vs continue (salta a la siguiente).
  • Anidar demasiados bucles y que el rendimiento se dispare.
  • Usar for cuando deberías usar while (o al revés) y complicar la lógica.
  • Modificar una lista mientras la recorres (se verá con detalle en estructuras).

Práctica de transferencia

  1. Escribe un bucle que imprima los números del 10 al 1.
  2. Suma solo los números pares del 1 al 20 con un for.
  3. Dada la lista precios = [12, 5, 8, 30], calcula el total y cuántos precios son mayores de 10. Usa continue para saltar los que no lo son al contarlos.
  4. Utiliza while para pedir números hasta que se introduzca 0 y muestra su suma. Ejecútalo como script en la terminal, porque usa input().
  5. Adapta el menú para que pregunte ¿Continuar? (s/n): con n termina, con s vuelve a preguntar y con cualquier otra respuesta muestra un aviso.

Qué debes comprobar: en el punto 1, que el último número impreso es 1 (revisa el fin de tu range); en el 2, que la suma es 110; en el 4, qué ocurre si el primer número que escribes ya es 0.

Producto evaluable

Cuaderno 04_bucles.py con:

  1. El factorial, la tabla de multiplicar y el patrón de asteriscos, cada uno con su celda Markdown que interprete el resultado.
  2. Una celda con un while que acumule una suma hasta una condición.
  3. Una celda que compare break y continue con dos ejemplos y explique la diferencia.

Formato de entrega: cuaderno marimo ejecutado, con salida esperada, interpretación y conclusión.

Resumen y referencia rápida

Construcción Cuándo Ejemplo
for ... in iterable Recorrer una colección/range for i in range(5)
while cond: Repetir hasta una condición while n > 0:
break Salir del bucle if x == 0: break
continue Salto a la siguiente vuelta if pares: continue
else en bucle Si no hubo break for ... else:
:= (walrus) Asignar y usar en una expresión if (n := len(x)) > 0:
range(inicio, fin, paso) Secuencia de números range(2, 8, 2)

Siguiente: 1.6 · Listas y tuplas.