Menu

range() em Python: start, stop, step e contagem decrescente

Como range() funciona em Python — start, stop, step, ranges negativos e por que ele é preguiçoso em vez de materializar uma lista.

Uma ferramenta para produzir números

range() faz exatamente uma coisa: produz uma sequência de inteiros. É o parceiro preferido dos laços for quando você precisa iterar um número específico de vezes ou percorrer um intervalo numérico.

A forma mais simples recebe um único argumento — o valor de stop:

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

Saída:

0
1
2
3
4

Dois detalhes que pegam iniciantes:

  1. A contagem começa em 0. range(5) te dá cinco números, começando em 0.
  2. O valor stop é exclusivo. range(5) para antes de 5 — não inclui o 5.

Essas regras são consistentes entre fatiamento, indexação e operações de range do Python. Uma vez que você internaliza "stop é exclusivo", para de te enganar.

Três formas

range() aceita um, dois ou três argumentos:

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

Step é o tamanho de cada salto. range(0, 20, 4) produz cada quarto número. Lembre disso na próxima vez que precisar de "cada outro item" ou "cada décima amostra".

Contagem decrescente

O passo pode ser negativo, o que permite contar para trás:

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

De novo, o stop é exclusivo — range(10, 0, -1) para antes de 0, não em 0. Para incluir 0, coloque o stop como -1:

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

range é preguiçoso

No Python 3, range() não constrói uma lista de números na memória. Ele retorna um objeto range leve que produz números um de cada vez, sob demanda. É por isso que você pode escrever:

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

Um "range" de um bilhão de números ocupa praticamente nada de memória. Os números são gerados conforme o laço pede.

Se você de fato precisa de uma lista dos números — porque quer modificar, ordenar ou indexar além do básico — converta explicitamente:

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

Na maioria das vezes, você não precisa da lista. for i in range(...) funciona direto.

Padrões comuns

Um punhado de receitas que você vai usar o tempo todo:

Faça algo n vezes.

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

O _ é uma convenção que significa "não me importo com este valor" — o Python não impõe, mas qualquer leitor reconhece a intenção.

Indexar uma sequência.

Prefira enumerate() em vez de range(len(...)), mas quando você especificamente precisa só do índice:

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

Ainda assim, na maioria das vezes enumerate(items) é mais limpo.

Iterar cada outro elemento.

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

Isso imprime a, c, e. Para fatiamento simples, porém, a sintaxe de fatiamento é ainda mais direta: items[::2].

Gerar uma lista numérica rápida.

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

Isso é uma list comprehension — coberta depois — mas o range é quem fornece os números.

O que range() não é

Duas bordas afiadas que vale saber:

  1. range só produz inteiros. Se você precisa de passos de ponto flutuante (como 0.0 a 1.0 em passos de 0.1), use numpy.arange ou um laço com seu próprio contador.
  2. range não funciona com iteráveis arbitrários. É especificamente para inteiros. Se está tentando "fazer range" sobre uma lista, você provavelmente está procurando enumerate ou a lista em si.

Juntando tudo

Um exemplo pequeno usando várias variações de uma vez:

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

Dois laços aninhados guiados por range, produzindo uma grade. Note que os dois laços começam em 1 — range(1, 6) — porque queremos rótulos de 1 a 5.

Entrando em coleções

Você já viu condições, os dois tipos de laços e range. Isso é controle de fluxo suficiente para guiar qualquer coleção. Próximo capítulo: as próprias coleções — listas, tuplas, sets e dicionários.

Perguntas frequentes

O que o range() faz em Python?

range() produz uma sequência de inteiros. range(n) dá 0 até n-1. range(start, stop) dá inteiros de start até (sem incluir) stop. range(start, stop, step) permite escolher o tamanho do passo, incluindo passos negativos para contar para trás.

O range() cria uma lista?

Não. No Python 3, range() retorna um objeto range leve que gera números sob demanda. É por isso que range(10**9) é instantâneo — não aloca de fato um bilhão de inteiros. Envolva em list(...) se realmente precisar de uma lista.

Como faço contagem decrescente com range() em Python?

Use um passo negativo: range(10, 0, -1) conta 10, 9, 8, ..., 1. Lembre que o valor stop é sempre exclusivo, então para incluir 0 você precisaria de range(10, -1, -1).

Aprenda a programar com o Coddy

COMEÇAR