Ir al contenido
wannacode

Bucles

En resumen: Un bucle repite un trozo de código tantas veces como haga falta: for con range recorre una serie de números, while repite mientras una condición es verdadera y break detiene el bucle.

Problema

¿Cuánto vas a ahorrar?

Decides ahorrar: el primer mes apartas 10 €, el segundo 20 €, el tercero 30 € y así, cada vez 10 € más. ¿Cuánto tendrás después de 4 meses?

total = 0
total += 1 * 10
total += 2 * 10
total += 3 * 10
total += 4 * 10
print(total)
Salida
100

Funciona. Pero en 3 años serían 36 líneas, casi iguales. Y si el número de meses se escribe con el teclado, no tienes ni idea de cuántas líneas escribir. Necesitas una forma de decir «repite esto tantas veces».

La idea

for: repite para cada número

Un trozo de código que se repite se llama bucle. El que más vas a usar es for. Aquí están los números del 1 al 10:

for i in range(1, 11):
print(i)
Salida
1
2
3
4
5
6
7
8
9
10

for i in range(1, 11): significa «para cada i entre los números que da range». i es el contador: en cada vuelta recibe el siguiente número. range tiene tres partes, separadas por comas:

  • Inicio: 1. El primer número. Si falta, como en range(10), el inicio es 0.
  • Final: 11. El final no se incluye: el último número es 10. Por eso range(1, 11) va del 1 al 10.
  • Paso: cuánto se suma cada vez. Si falta, es 1. range(3, 0, -1) cuenta hacia atrás: 3, 2, 1.

El cuerpo es lo que va sangrado 4 espacios después de los dos puntos, igual que con if.

Cada ejecución del cuerpo se llama iteración, o vuelta.

Más precisamente, para curiosos
  • El paso puede ser el que necesites: un número sí y otro no, hacia atrás. Y range(10) cuenta del 0 al 9: siguen siendo 10 vueltas. Por qué se cuenta desde 0 quedará claro en la lección sobre listas.
for i in range(1, 11, 2):
print(i, end=" ")
print()
for i in range(10, 0, -1):
print(i, end=" ")
print()
for i in range(10):
print(i, end=" ")
print()
Salida
1 3 5 7 9
10 9 8 7 6 5 4 3 2 1
0 1 2 3 4 5 6 7 8 9
  • En Python el contador sigue ahí después del bucle, con su último valor. En Java, C# y JavaScript desaparece después del bucle.
for i in range(1, 4):
print(i)
print("Después del bucle i vale", i)
Salida
1
2
3
Después del bucle i vale 3
  • Python no tiene un for con condición y paso como for (int i = 1; i <= 10; i++) en Java. Cuando necesitas «mientras algo sea verdadero», está while (lo vemos enseguida).

Míralo

Vuelta a vuelta

Este es el ahorro de la primera tarjeta, con un bucle. Fíjate en cómo cambian month y total.

total = 0
for month in range(1, 5):
total += month * 10
print(total) # 100
Paso a paso, en palabras
  1. total empieza en 0.
  2. month = 1, el primer número de range(1, 5). Entramos en el cuerpo.
  3. Vuelta 1: total += 1 * 10, total pasa a ser 10.
  4. month pasa a ser 2, el siguiente número de range. Una vuelta más, total pasa a ser 30.
  5. month 3: total pasa a ser 60.
  6. month 4: total pasa a ser 100.
  7. range(1, 5) no tiene más números: el valor final 5 no se incluye. El bucle termina y month se queda en 4.
  8. Después del bucle, total es 100.

El cuerpo es una línea y se escribe una sola vez. Para 36 meses solo cambias 5 por 37. Incluso puedes poner ahí una variable leída del teclado.

Pruébalo

Cuenta atrás

¿Qué imprimirá el programa?

for sec in range(3, 0, -1):
print(sec)
print("¡Ya!")
Respuesta

La idea

while: hasta que llegue el final

A veces no sabes de antemano cuántas vueltas habrá. La caja registradora lee precios hasta que el cajero introduce 0, y entonces da el total. Aquí for no encaja. while sí: repite mientras la condición sea verdadera.

total = 0
price = int(input())
while price != 0:
total += price
price = int(input())
print(f"Total: {total} €")
Entrada
12
4
7
0
Salida
Total: 23 €

El primer precio se lee antes del bucle, para que la condición tenga algo que comprobar. El siguiente se lee al final del cuerpo. Si el primer número es 0, el cuerpo no se ejecuta ni una vez.

A veces el cuerpo tiene que ejecutarse al menos una vez y la condición tiene que comprobarse después de la vuelta. Por ejemplo, una pregunta que se repite hasta que la respuesta es aceptable. Java, C# y JavaScript tienen do-while para esto. Python no. Escribes while True:, un bucle cuya condición siempre es verdadera, y dentro un break que lo detiene en cuanto la respuesta es buena (enseguida veremos más sobre break):

while True:
print("¿Cuántas entradas (de 1 a 10)?")
count = int(input())
if 1 <= count <= 10:
break
print(f"Entradas reservadas: {count}")
Entrada
0
15
3
Salida
¿Cuántas entradas (de 1 a 10)?
¿Cuántas entradas (de 1 a 10)?
¿Cuántas entradas (de 1 a 10)?
Entradas reservadas: 3
Más precisamente, para curiosos
  • Si la condición nunca se vuelve falsa, el bucle nunca termina. Es un bucle infinito: el programa se «cuelga» y tienes que detenerlo a mano. La causa más común es olvidar cambiar la variable de la condición, por ejemplo que falte price = … al final del cuerpo.
  • while True: sin ningún break dentro es un bucle infinito. Asegúrate de que haya un camino hasta el break.
  • Cualquier for se puede escribir como un while. Eliges el que se lee con más claridad: for para un número conocido de vueltas, while para «hasta que pase algo».

Pruébalo

Encuentra el error

El programa debería sumar los números del 1 al 5: 1 + 2 + 3 + 4 + 5 = 15. Imprime 10. ¿Qué línea tiene el error?

Elige la línea con el error.

La suma está en total, no en sum: en Python sum es el nombre de una función integrada y es mejor no ocuparlo.

La idea

break y continue

Dos palabras cambian el recorrido normal de un bucle.

continue salta el resto de la vuelta actual y pasa a la siguiente. Estás listando las horas de citas de 9 a 17, pero a las 13 es la pausa para comer:

for hour in range(9, 18):
if hour == 13:
continue
print(f"{hour}:00")
Salida
9:00
10:00
11:00
12:00
14:00
15:00
16:00
17:00

break detiene todo el bucle en el acto. Buscas el primer número entre el que se divide 91. En cuanto lo encuentras, no tiene sentido seguir:

n = 91
for d in range(2, n):
if n % d == 0:
print(f"{n} es divisible entre {d}")
break
Salida
91 es divisible entre 7
Más precisamente, para curiosos
  • break detiene solo el bucle en el que está. Si está en un bucle anidado (siguiente tarjeta), el exterior sigue.
  • Ya has visto while True: con un break dentro: un bucle que no termina por su condición, sino por un break en el lugar adecuado.

La idea

Un bucle dentro de otro

La sala de cine tiene 3 filas de 4 asientos. Quieres imprimir cada asiento. Para cada fila recorres todos sus asientos:

for row in range(1, 4):
for seat in range(1, 5):
print(f"[{row}-{seat}]", end="")
print()
Salida
[1-1][1-2][1-3][1-4]
[2-1][2-2][2-3][2-4]
[3-1][3-2][3-3][3-4]

Esto se llama bucles anidados. El bucle interior se recorre entero en cada vuelta del exterior: 3 filas · 4 asientos = 12 impresiones. end="" le dice a print que no pase a una línea nueva, así que los asientos quedan en una línea. El print() vacío después del bucle interior pasa a una línea nueva.

Pruébalo

Escalera

La primera fila debe tener una estrella, la segunda dos, la cuarta cuatro. ¿Qué va en el hueco?

for row in range(1, 5):
    for star in range():
        print("*", end="")
    print()

La idea

Números aleatorios para juegos

Un juego de dados necesita un número que el programa no conoce de antemano. Te lo da random:

import random
dice = random.randint(1, 6)
print(f"Ha salido {dice}")

random es un módulo: código ya hecho que viene con Python. Lo traes con import random al principio del archivo, igual que math.

random.randint(1, 6) da un número entero del 1 al 6. Cuidado: aquí se incluyen los dos límites, a diferencia de range.

Cada ejecución da un número distinto, así que aquí no hay salida. Y aquí tienes un bucle que tira el dado hasta que sale un seis:

import random
rolls = 0
while True:
dice = random.randint(1, 6)
rolls += 1
if dice == 6:
break
print(f"Un seis después de {rolls} tiradas")
Más precisamente, para curiosos
  • Si fijas un número inicial con random.seed(42), cada ejecución da la misma secuencia. Esto ayuda en las pruebas.
  • random.random() da un número decimal de 0 a 1 (sin incluir el 1), como Math.random() en JavaScript.
  • Los números no son aleatorios de verdad: se calculan con una fórmula. Sirven para juegos, pero no para contraseñas ni seguridad.

Ejercicio

Ejercicios con bucles

Resuelve los ejercicios en tu editor. Cada uno tiene una entrada y una salida de ejemplo para comparar con la tuya. El número se lee igual que en la lección «Entrada y salida».

1. Tabla de multiplicar. Lee un número e imprime sus productos con los números del 1 al 10.

Entrada
7
Salida
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 = 70

2. Número primo. Un número es primo si solo se divide entre 1 y entre sí mismo: 2, 3, 5, 7, 11… Lee un número y di si es primo. Pista: prueba los divisores desde el 2 hacia arriba y detente con break en el primero.

Entrada
91
Salida
91 no es primo

Para 11 la salida es «11 es primo».

3. Las cifras de un número. Lee un número entero positivo. Imprímelo al revés y la suma de sus cifras. Pista: n % 10 es la última cifra, y n // 10 quita la última cifra. Repite hasta que el número llegue a 0.

Entrada
2024
Salida
Al revés: 4202
Suma de las cifras: 8

4. Adivina el número. La computadora «piensa» un número del 1 al 100 y tú lo buscas. Después de cada intento el programa dice «Es menor.» o «Es mayor.», y al final cuántos intentos te hicieron falta. Escríbelo primero con el número secreto 37, para poder comprobarlo con el ejemplo:

Entrada
50
25
37
Salida
Es menor.
Es mayor.
¡Acertaste en 3 intentos!

Cuando funcione, cambia el 37 por un número aleatorio del 1 al 100. Ahora ni tú sabes la respuesta.

Más ejercicios

  • Del 1 al N. Lee N e imprime los números del 1 al N en una línea. Para 5: 1 2 3 4 5.
  • Factorial. N! = 1 · 2 · 3 · … · N. Para 5: 120. En Python un número entero no tiene límite superior: 20! es 2432902008176640000, y 30! sale igual de exacto.
  • Primos hasta N. Imprime todos los números primos hasta N. Para 20: 2 3 5 7 11 13 17 19. La comprobación del ejercicio 2 va dentro de un bucle sobre los números: bucles anidados.
  • Fibonacci. Cada número es la suma de los dos anteriores: 0, 1, 1, 2, 3, 5, 8… Lee N e imprime los N primeros números. Para 10: 0 1 1 2 3 5 8 13 21 34.
  • Cuadrado de estrellas. Lee N e imprime un cuadrado de N × N. Para 3:
Salida
* * *
* * *
* * *
  • Triángulo de estrellas. Lo mismo, pero cada fila tiene tantas estrellas como su número. Para 3:
Salida
*
* *
* * *
  • Cara o cruz. Lee N, lanza una moneda N veces con un número aleatorio (0 es cara, 1 es cruz) e imprime cuántas veces salió cada una. Cuanto mayor es N, más se acercan los dos números a N / 2.
  • Piedra, papel o tijera. Un jugador contra la computadora. El jugador escribe su elección, la computadora elige al azar y el programa dice quién gana. Con while True y break pregunta «¿Otra partida? (sí/no)» y al final imprime el marcador.

Test

Ponte a prueba

1. ¿Cuántas veces se ejecuta el cuerpo de for i in range(5):?
2. Python no tiene do-while. ¿Cómo escribes un bucle cuyo cuerpo se ejecute al menos una vez?
3. ¿Qué hace continue?
4. El bucle exterior da 3 vueltas y el interior da 4. ¿Cuántas veces se ejecuta el cuerpo del bucle interior?
5. ¿Qué línea da un número aleatorio del 1 al 6?

Creado por Ivo Gergov como parte de la campaña de Evo Tech por una educación accesible en programación ·