Francisco Javier Palacios PérezFco. Javier Palacios Pérez
Desarrollador de software
Bucles for y range() en Python: itera sin gestionar contadores

Bucles for y range() en Python: itera sin gestionar contadores

Bucles for y range() en Python: itera sin gestionar contadores

Bucles for y range() en Python: itera sin gestionar contadores

Ya sabes usar el while. Un contador, una condición, un incremento — cuatro líneas para imprimir los números del 1 al 10. Funciona. Pero hay algo que se puede mejorar. Con un for, el mismo resultado ocupa dos:

# while: you manage everything yourself
contador = 1
while contador <= 10:
    print(contador)
    contador += 1

# for: Python manages the counter for you
for i in range(1, 11):
    print(i)

Esa diferencia no es cosmética. Es conceptual: el for existe para los casos en los que sabes exactamente qué vas a iterar — ya sea una lista de datos, un rango de números, o las letras de un string. No tienes que gestionar el contador porque el propio bucle lo hace. Y cuando no tienes que gestionar el contador, no puedes olvidar actualizarlo.

¿Qué es un bucle for?

Un for recorre una secuencia de elementos, uno por uno, y ejecuta un bloque de código por cada elemento. Cuando llega al último, se detiene solo.

frutas = ["manzana", "pera", "uva"]

for fruta in frutas:
    print(fruta)  # Print each fruit
manzana
pera
uva

La estructura es for <variable> in <secuencia>:. En cada iteración, la variable (fruta) toma el valor del siguiente elemento. No indexas nada, no incrementas nada: el bucle se encarga.

Si eres como yo cuando empecé, en algún momento te preguntarás de dónde sale esa variable fruta. La respuesta es que Python la crea automáticamente cuando empieza el for. Y aquí viene algo que no todo el mundo sabe: después del bucle, esa variable sigue existiendo con el valor del último elemento que procesó.

for fruta in frutas:
    print(fruta)

print(fruta)  # "uva" — still alive after the loop

No es un bug. Es cómo funciona Python. Ya te alegrarás de saberlo algún día cuando estés depurando algo a las 11 de la noche y esa variable sea justo lo que necesitas.

range(): el generador de secuencias numéricas

Iterar sobre una lista de frutas está bien, pero muchas veces lo que necesitas es repetir algo un número determinado de veces — no recorrer una colección existente. Para eso está range(), que genera una secuencia de números enteros.

Tiene tres formas:

range(stop)

La más simple: genera números desde 0 hasta stop - 1.

for i in range(5):
    print(i)
0
1
2
3
4

Ojo al detalle: el 5 no está incluido. range(5) genera cinco números empezando por 0. En Python, los rangos son semiabiertos por la derecha — incluyen el inicio, excluyen el final. El mismo patrón que verás más adelante con el slicing de listas.

range(start, stop)

Cuando quieres empezar desde otro número:

for i in range(1, 6):
    print(i)  # 1, 2, 3, 4, 5
1
2
3
4
5

Del 1 al 5, sin trucos. Mucho más legible que range(5) con un + 1 después.

range(start, stop, step)

El tercer argumento es el paso: cuánto avanza la secuencia en cada iteración.

for i in range(0, 11, 2):
    print(i)  # Even numbers from 0 to 10
0
2
4
6
8
10

El paso también puede ser negativo para contar hacia atrás:

for i in range(10, 0, -1):
    print(i)  # Countdown from 10 to 1
10
9
8
7
6
5
4
3
2
1

Por ahora, no te agobies memorizando las tres variantes. La que usarás el 90% del tiempo es range(n) para repetir algo n veces, o range(1, n+1) cuando los números necesitan empezar en 1. Las demás las incorporarás a base de usarlas.

Iterar sobre otras secuencias

El for no entiende solo de listas y rangos. Funciona con cualquier cosa iterable — es decir, cualquier cosa que tenga elementos que recorrer.

Los strings son iterables — cada carácter es un elemento:

for letra in "Python":
    print(letra)
P
y
t
h
o
n

Y ya que aparecen en la siguiente lección, un adelanto: las listas también funcionan exactamente igual que viste con las frutas. El mecanismo del for es genérico — no le importa si estás recorriendo letras, números o cualquier otra cosa. El bucle es siempre el mismo.

break: salir antes de tiempo

Igual que en el while, puedes interrumpir un for antes de que llegue al final de la secuencia con break. En cuanto Python ejecuta un break, sale del bucle inmediatamente.

numeros = [3, 7, 2, 9, 4, 6, 1]

for numero in numeros:
    if numero == 9:
        print("Encontrado el 9, parando.")
        break   # No need to keep looking
    print(numero)
3
7
2
Encontrado el 9, parando.

Una vez que break se ejecuta, el resto de la lista (4, 6, 1) no se procesa. Si el elemento que buscas aparece al principio, te ahorras recorrer todo lo demás — algo importante cuando la lista tiene miles de elementos.

Aquí es donde se pone interesante: Python tiene un else para los bucles for. El bloque else se ejecuta solo si el bucle terminó sin interrumpirse con break. Si el break salta, el else se ignora:

emails = ["user@example.com", "admin@site.com", "support@company.com"]
buscar = "otro@email.com"

for email in emails:
    if email == buscar:
        print("Email encontrado.")
        break
else:
    print("Email no encontrado en la lista.")  # Runs if no break occurred
Email no encontrado en la lista.

Es uno de esos detalles de Python que sorprende a quien viene de otros lenguajes. Si no lo conocías, perfectamente normal — no es obvio, y la mayoría lo aprende cuando lo necesita.

Bucles anidados: un for dentro de otro

Un for puede estar dentro de otro for. Por cada iteración del bucle externo, el bucle interno completa todas las suyas:

for fila in range(1, 4):
    for columna in range(1, 4):
        print(f"({fila},{columna})", end=" ")  # Print on same line
    print()  # New line after each row
(1,1) (1,2) (1,3)
(2,1) (2,2) (2,3)
(3,1) (3,2) (3,3)

El caso de uso más clásico: una tabla de multiplicar.

for i in range(1, 6):
    for j in range(1, 6):
        resultado = i * j
        print(f"{resultado:3}", end="")  # Right-align in 3 chars
    print()
  1  2  3  4  5
  2  4  6  8 10
  3  6  9 12 15
  4  8 12 16 20
  5 10 15 20 25

Los bucles anidados funcionan, pero hay algo que conviene saber desde el principio: el tiempo de ejecución se multiplica. Un bucle de 100 iteraciones dentro de otro de 100 son 10.000 operaciones. Si añades un tercero de 100, son 1.000.000. Ese callback hell de la complejidad algorítmica del que todo el mundo huye cuando llega a estructuras de datos avanzadas — sí, ese — empieza aquí. Por ahora, con dos niveles vas sobrado.

for o while: la tabla definitiva

SituaciónUsar
Sabes cuántas veces repetirfor
Tienes una secuencia que recorrerfor
Leer un archivo de principio a finfor
Recorrer una lista, un string, un rangofor
La condición de parada es impredeciblewhile
Esperar input válido del usuariowhile
Juego que sigue hasta que el jugador pierdewhile
Bucle de reintentos con límite de tiempowhile

En la práctica, usarás for la mayoría de las veces. La mayoría de la iteración cotidiana en Python tiene una secuencia concreta que recorrer, y el for lo gestiona de forma más clara y directa que el while.


Con el for y range() en tu caja de herramientas, puedes recorrer cualquier secuencia sin llevar la cuenta a mano. El siguiente paso natural es tener algo interesante que recorrer: en el próximo tutorial aprenderás las listas, la estructura de datos más versátil de Python — cómo crearlas, acceder a sus elementos, y combinarlas con todo lo que ya sabes.

¡Nunca dejes de programar!


💡 Reto: Escribe un programa que genere e imprima las tablas de multiplicar del 1 al 10, formateadas de manera que cada resultado ocupe el mismo espacio (puedes usar f"{resultado:4}" para alinear). Bonus: pide al usuario que introduzca un número del 1 al 10 y muestra solo la tabla de ese número — con la posibilidad de pedir otra hasta que decida salir.