Saltar al contenido
IDE libre

Fundamentos

El bucle for y la función range() en Python

Aprende el bucle for en Python con range() de uno, dos y tres argumentos, recorre textos y secuencias y evita las trampas del límite que no entra.

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

Métricas de este artículo

Palabras
2528
Caracteres
13.226
Tiempo de lectura
~13 min

El for recorre una secuencia de valores y ejecuta el bloque una vez por cada valor. Cuando el programa necesita repetir algo un número conocido de veces, la secuencia viene de la función range(): range(5) entrega los números 0, 1, 2, 3 y 4, y el bucle da cinco vueltas. El punto que más atrapa a quien empieza es que el límite nunca entra en la cuenta: range(1, 6) va de 1 hasta 5.

El artículo anterior mostró el while, en que la persona escribe el valor inicial, la prueba y la actualización. El for junta esas tres piezas en una sola línea y deja que Python se ocupe de ellas. Este artículo explica el range() con uno, dos y tres argumentos, muestra que el for sirve para textos y para grupos de valores, acompaña los usos más comunes (sumas, máximos, tablas) y lista los errores que aparecen en las clases.

Del while al for

A la izquierda, un while con cuatro líneas coloreadas: i igual a 1, while i menor o igual a 5, print(i) e i más igual a 1. A la derecha, el for equivalente, con dos líneas: for i in range(1, 6) y print(i). Un texto explica que el for reúne valor inicial, prueba y actualización en la primera línea. Una franja dice que las dos versiones imprimen de 1 a 5 y que el 6 es el límite y no entra. Dos cuadros al final indican cuándo usar for, cuando se sabe qué recorrer, y cuándo usar while, cuando el final depende de algo que solo aparece corriendo.
El mismo trabajo con while y con for: el for se ocupa de tres de las cuatro piezas.

Mira la tabla del 2 escrita con for:

for i in range(1, 6):
    print("2 x", i, "=", 2 * i)
soma = 0
for n in range(1, 11):
    soma = soma + n
print("suma de 1 a 10:", soma)
print(sum(range(1, 11)))

La salida es la tabla de 2 x 1 = 2 a 2 x 5 = 10, después suma de 1 a 10: 55 y, en la última línea, 55 otra vez. La primera línea del bucle tiene la palabra for, el nombre de la variable que recibe cada valor (i), la palabra in, la secuencia (range(1, 6)) y los dos puntos. El bloque con sangría de abajo es el cuerpo. No hay i = 1 antes ni i += 1 adentro: el for toma el primer valor del range en la primera vuelta, el segundo en la segunda, y termina cuando los valores se acaban.

La segunda parte del ejemplo es el patrón del acumulador, visto en el artículo sobre por qué repetir: la variable soma empieza en 0 y recibe cada n. El resultado, 55, es el de la suma de los diez primeros números. La función sum() hace la misma cuenta de una vez, y vale conocerla, pero el bucle con acumulador es lo que se aprende primero porque el mismo diseño sirve para productos, conteos y máximos.

La elección entre los dos bucles sigue una regla simple. Usa for cuando el programa ya sabe qué recorrer: los números de 1 a 10, los elementos de un grupo, las letras de un texto. Usa while cuando el final depende de algo que solo aparece con el programa corriendo, como una respuesta escrita o una lectura de sensor.

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

La función range()

Tres rectas numéricas de 0 a 10. En la primera, range(5) marca en verde los puntos de 0 a 4, y el 5 aparece como una bolita roja de trazos llamada parada. En la segunda, range(2, 8) marca de 2 a 7, con la parada en el 8. En la tercera, range(10, 0, -3) marca 10, 7, 4 y 1, con flechas de paso menos 3 entre ellos y la parada en el 0. A la derecha de cada recta está la lista resultante.
range(inicio, parada, paso): el inicio entra, la parada nunca entra.

El range() tiene tres formas, y la figura muestra cada una en una recta numérica. Para ver los números que produce, el ejemplo los convierte en lista con list():

print(list(range(5)))
print(list(range(2, 8)))
print(list(range(10, 0, -3)))
print(list(range(0, 10, 3)))
print(list(range(5, 2)))
print(list(range(0)))
print(range(5))
print(len(range(0, 10, 3)))
print(3 in range(5), 5 in range(5))

La salida tiene nueve líneas: [0, 1, 2, 3, 4], [2, 3, 4, 5, 6, 7], [10, 7, 4, 1], [0, 3, 6, 9], [], [], range(0, 5), 4 y True False. Las formas son:

  • range(parada) empieza en 0, avanza de 1 en 1 y se detiene antes de la parada. range(5) da 0, 1, 2, 3, 4.
  • range(inicio, parada) empieza en el inicio. range(2, 8) da 2, 3, 4, 5, 6, 7.
  • range(inicio, parada, paso) avanza de paso en paso. range(0, 10, 3) da 0, 3, 6, 9, y range(10, 0, -3), con paso negativo, cuenta hacia atrás: 10, 7, 4, 1.

Tres detalles aparecen en la salida. El primero es que range(5, 2) y range(0) están vacíos: un for sobre ellos no corre ninguna vez, y el programa sigue adelante sin error. Para contar hacia atrás hace falta un paso negativo, como en el range(10, 0, -3). El segundo es que print(range(5)) no muestra los números sino range(0, 5): el range es una descripción de la secuencia, y no una lista ya lista. El list() es lo que la arma. El tercero es que el len() y el in funcionan directamente sobre él.

El range no gasta memoria

Como el range guarda solo el inicio, la parada y el paso, y produce cada número cuando el bucle lo pide, sirve para secuencias enormes sin costo:

for i in range(1000000):
    if i == 3:
        break
print("paró en", i)
print(len(range(1000000)))

La salida es paró en 3 y 1000000. El programa nunca construyó una lista de un millón de elementos. Esto importa en la ESP32, que tiene poca memoria: un bucle con range(10000) cuesta lo mismo que uno con range(10), mientras que una lista con diez mil números ocuparía una parte de la RAM de la placa. El break que aparece en el ejemplo sale del bucle antes del final, y es tema de un artículo más adelante.

La variable después del bucle

Después del for, la variable del bucle sigue existiendo y guarda el último valor que recibió:

for i in range(5):
    print(i)
print("después, i vale", i)

La salida es de 0 a 4 y después, i vale 4. El i vale 4, y no 5: el 5 nunca fue entregado al bucle. Por eso se dice que el range(5) hace cinco vueltas y el i llega a 4.

Contando hacia atrás y de paso en paso

El paso negativo hace la cuenta regresiva, y el paso mayor que 1 sirve para saltar valores, como los múltiplos de 5 o los ángulos de un servo:

for i in range(10, 0, -3):
    print(i)
for i in reversed(range(3)):
    print("rev", i)
for graus in range(0, 181, 45):
    print(graus)

La salida es 10, 7, 4, 1, después rev 2, rev 1, rev 0 y por último 0, 45, 90, 135, 180. La función reversed() es una segunda forma de invertir el range. Fíjate en el límite del último bucle: para que el 180 entre, la parada es 181, y ese tipo de ajuste "uno de más" es lo que más genera dudas.

Recorriendo textos y grupos

El for no necesita range(): recorre cualquier secuencia. Un texto entrega las letras, una tupla entrega los elementos:

for letra in "ESP32":
    print(letra)
for dia in ("lun", "mar", "mie"):
    print(dia)
for i in range(3):
    for j in range(3):
        print(i * j, end=" ")
    print()

La salida es E, S, P, 3 y 2, después lun, mar y mie y, al final, una cuadrícula de tres líneas: 0 0 0, 0 1 2 y 0 2 4. El tercer bucle es un for dentro de otro, y vale la misma regla del while: el de adentro corre completo en cada vuelta del de afuera. La cuadrícula muestra la tabla de multiplicar de 0 a 2.

Cuando se necesita el número de la vuelta junto con el valor, la función enumerate() entrega los dos:

for i, dia in enumerate(("lun", "mar", "mie")):
    print(i, dia)
for i, dia in enumerate(("lun", "mar"), 1):
    print(i, dia)
for a, b in ((1, 2), (3, 4)):
    print(a + b)

La salida es 0 lun, 1 mar, 2 mie, después 1 lun y 2 mar y, por último, 3 y 7. El enumerate numera a partir de 0, o a partir del número dado como segundo argumento (el 1 del segundo bucle). El tercer bucle muestra que el for puede separar un par en dos variables, a y b, en cada vuelta. El ejemplo usa tuplas porque las listas, con todos sus recursos, son tema de un artículo más adelante en la serie.

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

Los patrones de siempre, ahora con for

El acumulador, el contador y el máximo son los mismos de cualquier bucle. Con las lecturas de un sensor guardadas en una tupla, el programa calcula el promedio, halla el mayor valor y muestra cada posición:

leituras = (512, 530, 498, 505, 521)
soma = 0
for v in leituras:
    soma = soma + v
print("promedio", soma / len(leituras))
maior = leituras[0]
for v in leituras:
    if v > maior:
        maior = v
print("mayor", maior)
for i in range(len(leituras)):
    print(i, leituras[i])

La salida es promedio 513.2, mayor 530 y cinco líneas de 0 512 a 4 521. El leituras[0] toma el elemento de posición 0, el primero, y el leituras[i] toma el de la posición i. Las posiciones empiezan en 0, lo que combina con el range(len(leituras)): va de 0 hasta el último índice, 4. El patrón del máximo empieza con el primer valor, y no con 0, porque así funciona también cuando todos los valores son negativos. Cuando solo interesa el valor, y no la posición, el primer estilo (for v in leituras) es más claro y más corto que el range(len(...)).

Salir antes o saltar una vuelta

Dos comandos cambian el ritmo del bucle: el break sale de él de una vez y el continue salta a la próxima vuelta.

for i in range(5):
    if i == 3:
        break
    print(i)
for i in range(5):
    if i % 2 == 0:
        continue
    print("impar", i)

La salida es 0, 1, 2, después impar 1 e impar 3. En el primer bucle el break interrumpe todo cuando i llega a 3, y el 3 no se imprime. En el segundo, el continue abandona el resto del cuerpo cuando i es par y va a la vuelta siguiente, así que solo se imprimen los impares. Los detalles de break y continue quedan para el artículo dedicado a ellos.

Qué cambia en la ESP32

El for y el range son los mismos del Python del computador. El uso más común en hardware es barrer un rango de valores, como el brillo de un LED con PWM:

from machine import Pin, PWM
import time
led = PWM(Pin(2), freq=1000)
for duty in range(0, 1024, 256):
    led.duty(duty)
    print("duty", duty)
    time.sleep_ms(100)
led.duty(0)
print("fin")

La salida es duty 0, duty 256, duty 512, duty 768 y fin. El range(0, 1024, 256) da cuatro escalones de brillo, y el time.sleep_ms sostiene cada uno por un instante, para que se pueda ver el cambio. El artículo sobre PWM, LED, zumbador y servo explica el duty y el rango de valores; aquí lo que importa es que el paso del range ajusta la suavidad de la transición.

El range() solo acepta números enteros. Para valores decimales, la manera es calcular a partir del entero de la vuelta, y no sumar un paso decimal varias veces:

for i in range(0, 11, 5):
    print(i / 10)
x = 0.0
for i in range(10):
    x = x + 0.1
print(x, x == 1.0)

La salida es 0.0, 0.5 y 1.0 en la primera parte, y 1.0000001 False en la segunda. La división i / 10 parte de un entero exacto y da 0,5 sin error. La suma de 0,1 diez veces acumula el error de redondeo del float de 32 bits: el resultado queda en 1.0000001 y la comparación con 1 falla. En el Python del computador, el float de 64 bits da 0.9999999999999999, también distinto de 1. El for con range evita el problema del bucle while con decimales, porque el número de vueltas es fijo, pero el valor acumulado aún carga el error.

Errores comunes y cómo reconocerlos

Seis tarjetas en dos filas de tres. range(1, 5) produce 1 2 3 4, porque el 5 no entra. range(5, 1) no produce nada, porque falta el paso negativo. range(2.5) da TypeError, porque range solo acepta enteros. range(1, 10, 0) da ValueError, porque el paso no puede ser cero. print(range(3)) muestra range(0, 3), que no es una lista. Cambiar la i dentro del cuerpo no afecta la vuelta siguiente, porque el for toma el próximo valor del range. Una franja dice que las dos primeras dan un resultado equivocado sin avisar y las dos siguientes dan error.
Seis trampas del for y del range y lo que produce cada una.

Las dos primeras tarjetas de la figura son errores de lógica que Python no acusa. range(1, 5) entrega 1, 2, 3 y 4, y quien quería hasta 5 pierde el último. range(5, 1) no entrega nada, y el bucle no corre, sin mensaje. Los dos siguientes dan error de verdad:

for i in range(2.5):
    print(i)
Traceback (most recent call last):
  File "main.py", line 1, in <module>
TypeError: can't convert float to int

Los mensajes del simulador (MicroPython) y del Python del computador difieren en la redacción:

ErrorSimulador (MicroPython)Python en el computador
range(2.5)TypeError: can't convert float to intTypeError: 'float' object cannot be interpreted as an integer
range(1, 10, 0)ValueError: zero stepValueError: range() arg 3 must not be zero
for i in 5:TypeError: 'int' object isn't iterableTypeError: 'int' object is not iterable
falta el : en el forSyntaxError: invalid syntax (línea 1)SyntaxError: expected ':'
cuerpo sin sangríaSyntaxError: invalid syntax (línea 2)IndentationError: expected an indented block after 'for' statement on line 1

"Iterable" quiere decir "algo que se puede recorrer", y un número suelto, como el 5 del for i in 5:, no lo es. Lo que el alumno quería era range(5).

En el aula: dónde suele tropezar el for

Los casos de abajo se repiten en los grupos que acaban de aprender el range.

El límite que no entra

Es el error número uno. El ejercicio pide los números de 1 a 10 y el programa muestra de 1 a 9, porque el alumno escribió range(1, 10). La frase que lo resuelve: el primer número del range entra, el segundo no. Para llegar hasta 10, la parada es 11.

Cambiar la i dentro del bucle

Algunos alumnos creen que sumar algo a la i dentro del cuerpo va a "saltar" vueltas. No salta:

for i in range(3):
    print("antes", i)
    i = i + 10
    print("después", i)

La salida es antes 0, después 10, antes 1, después 11, antes 2 y después 12. La i cambia dentro de la vuelta, pero en la vuelta siguiente el for toma el próximo valor del range e ignora el cambio. Para saltar valores, el camino es el paso del range; para un bucle que cambia su propio contador, el while.

Esperar una lista

El print(range(5)) muestra range(0, 5), y el alumno cree que algo se rompió. El list(range(5)) muestra los números.

Usar el for donde hacía falta el while

Un programa que pide notas hasta que el usuario escriba -1 no sabe cuántas vueltas dará, así que el range no se aplica. La pregunta de decisión es: ¿el número de vueltas se conoce antes de que el bucle empiece?

El nombre de la variable que se repite

En dos bucles anidados con la misma variable (for i dentro de for i), el de adentro sobrescribe el de afuera y el resultado confunde. Nombres distintos, como i y j, o nombres con sentido, como linha y coluna, evitan el problema. Cuando la variable del bucle no se usa en el cuerpo, la convención es llamarla _, como en for _ in range(3):, que repite tres veces sin necesitar el número.

La sangría y los dos puntos

Los errores de sintaxis del for son los mismos del if y del while: dos puntos olvidados y cuerpo sin sangría. El simulador dice solo invalid syntax y la línea. El artículo sobre if y else tiene la lista de errores de sangría.

Ejercicio: tabla de temperaturas

Convertir grados Celsius en Fahrenheit, de 0 a 100 de 25 en 25, con la fórmula F = C * 9 / 5 + 32. Es un ejercicio de range con paso, y la tabla muestra el bucle funcionando.

for c in range(0, 101, 25):
    f = c * 9 / 5 + 32
    print(c, "C =", f, "F")

La salida tiene cinco líneas: 0 C = 32.0 F, 25 C = 77.0 F, 50 C = 122.0 F, 75 C = 167.0 F y 100 C = 212.0 F. El 101 es la parada que deja entrar al 100. La división con / devuelve float, y por eso los resultados aparecen con .0.

Para una versión interactiva, la tabla de multiplicar del número que la persona escriba usa el input() y el int() antes del bucle:

n = int(input("Tabla del: "))
for i in range(1, 11):
    print(n, "x", i, "=", n * i)

Con la entrada 5, la salida va de 5 x 1 = 5 a 5 x 10 = 50. El int() es el del artículo sobre conversión de tipos, y el bucle for solo empieza después de que el número fue leído.

Preguntas frecuentes

¿El range puede empezar en 1?

Puede: range(1, 11) va de 1 a 10. Sin el primer argumento, el range empieza en 0, y eso combina con la forma de numerar posiciones que usa Python.

¿El range acepta números negativos?

Acepta en el inicio, en la parada y en el paso. range(-3, 3) va de -3 a 2, y range(5, -1, -1) cuenta de 5 a 0.

¿Cómo hago un bucle de 0 a 1 de 0,1 en 0,1?

Usa range(0, 11) y divide cada valor entre 10, como en el ejemplo del i / 10. El range solo trabaja con enteros.

¿Cuál es la diferencia entre for i in range(len(x)) y for item in x?

El primero recorre las posiciones, y el segundo recorre los valores. Prefiere el segundo cuando la posición no sea necesaria.

¿El for puede tener else?

Puede, y el bloque del else corre cuando el bucle termina sin break. Es tema del artículo sobre break, continue y el else de los bucles.

Para continuar

La ruta Lógica con Python tiene los desafíos de for y range. La Tabla del 2 y la Suma de 1 a 10 son los más directos, los Pares de 1 a 10 y los Múltiplos de 5 piden el paso y el límite con cuidado. Si el while todavía es la primera idea que viene a la cabeza, relee el artículo El bucle while.

El próximo tema es el "hacer-mientras": cómo repetir un bloque que necesita correr al menos una vez, con while True y break, ya que Python no tiene un comando propio para eso.

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