Saltar al contenido
bucles.py · devschool

Bucles en Python

Lección 6 de 19 · 9 min de lectura · Actualizado el

En esta lección
  1. for: recorrer una secuencia
  2. range: repetir un número de veces
  3. enumerate: el elemento y su posición
  4. zip: recorrer dos listas a la vez
  5. Recorrer un diccionario
  6. Acumuladores y contadores
  7. while: repetir mientras se cumpla una condición
  8. break y continue
  9. else en los bucles
  10. Bucles anidados
  11. Ejemplos prácticos
  12. Errores frecuentes
  13. Resumen

Un bucle repite un bloque de código varias veces. Sin bucles, para mostrar la tabla del 7 tendrías que escribir diez print; con un bucle, dos líneas. En esta lección verás los dos bucles de Python, for y while, cómo controlarlos con break y continue, y patrones que usarás constantemente: acumuladores, contadores, recorrer dos listas a la vez y validar lo que escribe el usuario.

for: recorrer una secuencia

En Python, for recorre directamente los elementos de una lista, un texto o cualquier colección. En cada vuelta, la variable toma el siguiente valor:

frutas = ["manzana", "pera", "kiwi"]
for fruta in frutas:
    print("Me gusta la", fruta)
# Me gusta la manzana
# Me gusta la pera
# Me gusta la kiwi

Como en los condicionales, la línea del for termina en : y el cuerpo va con sangría. A cada repetición se le llama iteración.

Una cadena también es una secuencia, así que se recorre letra a letra:

for letra in "sol":
    print(letra)
# s
# o
# l

range: repetir un número de veces

Cuando no tienes una lista sino que quieres repetir algo n veces, usa range, que genera una secuencia de números:

for i in range(3):
    print("Vuelta", i)
# Vuelta 0
# Vuelta 1
# Vuelta 2

range admite hasta tres argumentos: range(inicio, fin, paso). El fin nunca se incluye:

LlamadaNúmeros que genera
range(5)0, 1, 2, 3, 4
range(1, 6)1, 2, 3, 4, 5
range(0, 11, 2)0, 2, 4, 6, 8, 10
range(10, 0, -1)10, 9, 8, …, 1
range(5, 1)nada (el inicio ya es mayor que el fin)

¿Por qué el fin no se incluye? Porque así range(n) da exactamente n números y encaja con los índices de las listas, que empiezan en 0.

Para ver los números de un range de golpe, conviértelo en lista: list(range(1, 6)) da [1, 2, 3, 4, 5].

Ejemplo: la tabla de multiplicar

numero = 7
for i in range(1, 11):
    print(f"{numero} x {i:2} = {numero * i:2}")
# 7 x  1 =  7
# 7 x  2 = 14
# ...
# 7 x 10 = 70

El :2 de la f-string reserva dos huecos para que las columnas queden alineadas.

enumerate: el elemento y su posición

Si al recorrer una lista necesitas también el número de posición, no uses range(len(lista)): usa enumerate, que devuelve parejas (posición, elemento):

tareas = ["estudiar", "comprar", "entrenar"]
for posicion, tarea in enumerate(tareas, start=1):
    print(f"{posicion}. {tarea}")
# 1. estudiar
# 2. comprar
# 3. entrenar

start=1 hace que empiece a contar en 1, más natural para mostrar al usuario.

zip: recorrer dos listas a la vez

zip empareja los elementos de varias listas por posición:

alumnos = ["Ana", "Luis", "Eva"]
notas = [8, 4.5, 6]
for alumno, nota in zip(alumnos, notas):
    print(f"{alumno}: {nota}")
# Ana: 8
# Luis: 4.5
# Eva: 6

Si las listas tienen distinta longitud, zip se detiene en la más corta.

Recorrer un diccionario

Un for sobre un diccionario recorre sus claves. Con .items() obtienes clave y valor:

precios = {"café": 1.5, "tostada": 2.2}
for producto, precio in precios.items():
    print(f"{producto}: {precio:.2f} €")
# café: 1.50 €
# tostada: 2.20 €

Acumuladores y contadores

Uno de los usos más comunes de un bucle es acumular un resultado. Se crea una variable antes del bucle y se actualiza en cada vuelta:

compras = [12.5, 3.2, 40, 7.8]

total = 0                 # acumulador
caras = 0                 # contador
for importe in compras:
    total += importe
    if importe > 10:
        caras += 1

print(f"Total: {total:.2f} €")
print(f"Compras de más de 10 €: {caras}")
# Total: 63.50 €
# Compras de más de 10 €: 2

La clave es inicializar fuera del bucle. Si escribes total = 0 dentro, se pone a cero en cada vuelta.

El mismo patrón sirve para buscar el máximo, construir un texto o llenar una lista:

palabras = ["sol", "murciélago", "pan"]
mas_larga = ""
for palabra in palabras:
    if len(palabra) > len(mas_larga):
        mas_larga = palabra
print(mas_larga)
# murciélago

(Para sumas y máximos simples, Python ya tiene sum() y max(), que verás en Listas.)

while: repetir mientras se cumpla una condición

for es para cuando sabes qué vas a recorrer. while es para cuando no sabes cuántas vueltas hará falta: repite mientras la condición sea verdadera.

ahorro = 0
semanas = 0
while ahorro < 100:
    ahorro += 15
    semanas += 1
print(f"Llegas a {ahorro} € en {semanas} semanas")
# Llegas a 105 € en 7 semanas

La condición se comprueba antes de cada vuelta. Si es falsa desde el principio, el cuerpo no se ejecuta ni una vez.

Cuidado: algo dentro del bucle tiene que acabar haciendo falsa la condición. Si olvidas ahorro += 15, el bucle no terminará nunca (bucle infinito). Si te pasa, detén el programa con Ctrl + C.

break y continue

  • break sale del bucle inmediatamente.
  • continue salta al principio de la siguiente vuelta, sin ejecutar el resto del cuerpo.
for numero in range(1, 20):
    if numero % 2 == 0:
        continue       # salta los pares
    if numero > 9:
        break          # termina al pasar de 9
    print(numero)
# 1
# 3
# 5
# 7
# 9

while True con break

Un patrón muy habitual: un bucle que en principio no termina y del que se sale con break cuando se cumple algo. Es ideal para menús:

while True:
    opcion = input("1) Jugar  2) Salir: ")   # el usuario escribe 2
    if opcion == "2":
        print("Adiós")
        break
    print("¡A jugar!")
# Adiós

else en los bucles

Python tiene algo poco común: un else detrás de un for o un while. Se ejecuta si el bucle terminó sin break. Es útil para búsquedas: “lo he recorrido todo y no lo he encontrado”.

invitados = ["Ana", "Luis", "Eva"]
buscado = "Marta"

for persona in invitados:
    if persona == buscado:
        print(f"{buscado} está invitada")
        break
else:
    print(f"{buscado} no está en la lista")
# Marta no está en la lista

Si Marta estuviera en la lista, el break se ejecutaría y el else no.

Bucles anidados

Un bucle dentro de otro: por cada vuelta del exterior, el interior se ejecuta entero.

for fila in range(1, 4):
    for columna in range(1, 4):
        print(fila * columna, end="\t")
    print()   # salto de línea al terminar cada fila
# 1	2	3
# 2	4	6
# 3	6	9

El bucle interior se ejecuta 3 × 3 = 9 veces. Con listas grandes, los bucles anidados pueden ser lentos: 1000 × 1000 es un millón de vueltas.

Cuidado: break solo sale del bucle más interno. Para salir de los dos, lo más limpio es meter el código en una función y usar return.

Ejemplos prácticos

Validar la entrada del usuario

Pedir un número hasta que el usuario escriba uno válido:

while True:
    texto = input("Edad: ")          # el usuario escribe "abc", luego "25"
    if texto.isdigit():
        edad = int(texto)
        break
    print("Escribe solo números")
print(f"Tienes {edad} años")
# Escribe solo números
# Tienes 25 años

isdigit() comprueba que el texto solo tenga dígitos antes de convertirlo, así int() no falla. Más adelante verás otra forma con excepciones.

Juego: adivina el número

import random

secreto = random.randint(1, 100)
intentos = 0

while True:
    intento = int(input("Adivina el número (1-100): "))
    intentos += 1

    if intento < secreto:
        print("Más alto")
    elif intento > secreto:
        print("Más bajo")
    else:
        print(f"¡Correcto! Lo has adivinado en {intentos} intentos")
        break
  • import random carga el módulo de números aleatorios, y random.randint(1, 100) devuelve un entero entre 1 y 100, ambos incluidos.
  • El contador intentos es un acumulador.
  • while True repite hasta el break del acierto.

Reto para ti: limita el juego a 7 intentos usando while intentos < 7 y un else en el bucle para decir “Has perdido”.

Errores frecuentes

  • Esperar que range(1, 10) incluya el 10: el fin nunca se incluye. Usa range(1, 11).
  • Bucle infinito: la condición del while nunca se vuelve falsa. Revisa que la variable cambie dentro del bucle.
  • Inicializar el acumulador dentro del bucle: el total se reinicia en cada vuelta.
  • Modificar una lista mientras la recorres: borrar elementos de lista dentro de for x in lista se salta elementos. Recorre una copia (lista[:]) o crea una lista nueva.
  • Sangría del else: el else de un bucle va alineado con el for, no con el if. Si lo alineas con el if, cambia por completo el significado.
  • Usar range(len(lista)) sin necesidad: recorre la lista directamente o usa enumerate.

Resumen

HerramientaPara qué
for x in secuenciaRecorrer listas, textos, diccionarios…
range(inicio, fin, paso)Repetir con números; el fin no se incluye
enumerate(lista, start=1)Posición y elemento a la vez
zip(a, b)Recorrer varias listas en paralelo
while condicionRepetir sin saber cuántas veces
breakSalir del bucle
continuePasar a la siguiente vuelta
else del bucleSe ejecuta si no hubo break
while True + breakMenús y validación de entrada

Pon a prueba lo que has aprendido

[Python] ¿Qué números muestra este bucle?
for i in range(1, 4):
    print(i)

[Python] ¿Qué muestra este código?
for n in [1, 3, 5]:
    if n % 2 == 0:
        print("Hay un par")
        break
else:
    print("Sin pares")

[Python] Se quería sumar del 1 al 4. ¿Qué muestra este código?
for i in range(1, 5):
    total = 0
    total += i
print(total)

¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.