Menu

range() en Python: start, stop, step y contar hacia atrás

Cómo funciona range() en Python — start, stop, step, ranges negativos, y por qué es perezoso en vez de materializar una lista.

Una herramienta para producir números

range() hace exactamente una cosa: produce una secuencia de enteros. Es el compañero de referencia para los bucles for cuando necesitas iterar un número específico de veces o recorrer un intervalo numérico.

La forma más simple toma un único argumento — el valor de stop:

main.py
Output
Click Run to see the output here.

Salida:

0
1
2
3
4

Dos detalles que pillan a los novatos:

  1. Contar empieza en 0. range(5) te da cinco números, empezando desde 0.
  2. El valor de stop es exclusivo. range(5) se detiene antes de 5 — no incluye 5.

Estas reglas son consistentes en el slicing, la indexación y las operaciones de range de Python. Una vez que interiorizas "stop es exclusivo", deja de tropezarte.

Tres formas

range() acepta uno, dos o tres argumentos:

main.py
Output
Click Run to see the output here.

Step es el tamaño de cada salto. range(0, 20, 4) produce cada cuarto número. Tenlo en mente la próxima vez que necesites "cada segundo elemento" o "cada décima muestra".

Contar hacia atrás

El paso puede ser negativo, lo que te deja contar al revés:

main.py
Output
Click Run to see the output here.

De nuevo, el stop es exclusivo — range(10, 0, -1) se detiene antes de 0, no en 0. Para incluir 0, haz que el stop sea -1:

main.py
Output
Click Run to see the output here.

range es perezoso

En Python 3, range() no construye una lista de números en memoria. Devuelve un objeto range ligero que produce números uno a uno, bajo demanda. Por eso puedes escribir:

main.py
Output
Click Run to see the output here.

Un "range" de mil millones de números no ocupa prácticamente memoria. Los números se generan según los pide el bucle.

Si de verdad necesitas una lista de los números — porque quieras modificarla, ordenarla o indexarla más allá de lo básico — convierte explícitamente:

main.py
Output
Click Run to see the output here.

La mayor parte del tiempo no necesitas la lista. for i in range(...) funciona directamente.

Patrones comunes

Un puñado de recetas que usarás constantemente:

Hacer algo n veces.

main.py
Output
Click Run to see the output here.

El _ es una convención que significa "no me importa este valor" — Python no lo impone, pero cualquier lector reconocerá la intención.

Indexar en una secuencia.

Prefiere enumerate() sobre range(len(...)), pero cuando necesitas específicamente solo el índice:

main.py
Output
Click Run to see the output here.

Aún así, la mayor parte del tiempo enumerate(items) es más limpio.

Iterar cada segundo elemento.

main.py
Output
Click Run to see the output here.

Eso imprime a, c, e. Para slicing simple, la sintaxis de slicing es todavía más directa: items[::2].

Generar una lista numérica rápida.

main.py
Output
Click Run to see the output here.

Eso es una list comprehension — la cubriremos más adelante — pero range es lo que provee los números.

Lo que range() no es

Dos bordes afilados que vale la pena conocer:

  1. range solo produce enteros. Si necesitas pasos de coma flotante (como de 0.0 a 1.0 en incrementos de 0.1), usa numpy.arange o un bucle con tu propio contador.
  2. range no funciona con iterables arbitrarios. Es específicamente para enteros. Si estás intentando hacer "range" sobre una lista, probablemente estás buscando enumerate o la lista en sí.

Juntándolo todo

Un pequeño ejemplo usando varias variaciones de una vez:

main.py
Output
Click Run to see the output here.

Dos bucles anidados gobernados por range, produciendo una rejilla. Fíjate en que ambos bucles empiezan en 1 — range(1, 6) — porque queremos etiquetas del 1 al 5.

Entrando en las colecciones

Ya has visto condiciones, los dos tipos de bucle y range. Eso es suficiente flujo de control para manejar cualquier colección. Siguiente capítulo: las colecciones en sí — listas, tuplas, sets y diccionarios.

Preguntas frecuentes

¿Qué hace range() en Python?

range() produce una secuencia de enteros. range(n) da de 0 a n-1. range(start, stop) da enteros desde start hasta pero sin incluir stop. range(start, stop, step) te deja elegir el tamaño del paso, incluidos pasos negativos para contar hacia atrás.

¿range() crea una lista?

No. En Python 3, range() devuelve un objeto range ligero que genera números bajo demanda. Por eso range(10**9) es instantáneo — en realidad no reserva mil millones de enteros. Envuélvelo en list(...) si de verdad necesitas una lista.

¿Cómo cuento hacia atrás con range() en Python?

Usa un paso negativo: range(10, 0, -1) cuenta 10, 9, 8, ..., 1. Recuerda que el valor stop siempre es exclusivo, así que para incluir 0 necesitarías range(10, -1, -1).

Aprende a programar con Coddy

COMENZAR