Módulo 4 - Programação funcional

itertools: iteradores poderosos

10 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026

O que você vai aprender

  • Gerar sequências com count e cycle, inclusive infinitas.
  • Combinar iteráveis com chain sem criar listas intermediárias.
  • Fatiar iteradores com islice de forma preguiçosa.
  • Agrupar itens consecutivos com groupby.

Gerar e combinar sequências

O itertools é um módulo da biblioteca padrão cheio de ferramentas para trabalhar com iteradores de forma eficiente. Algumas produzem sequências. O count gera números indefinidamente, começando de onde você mandar e no passo que quiser, um contador infinito. O cycle percorre um iterável repetidas vezes, voltando ao começo para sempre, útil para revezar opções. Como são infinitos, você sempre os combina com algo que os limite, como um islice ou uma condição de parada, para não rodar sem fim.

from itertools import count, cycle, islice

# count: contador infinito a partir de 10, de 2 em 2
contador = count(10, 2)
print(list(islice(contador, 5)))  # [10, 12, 14, 16, 18]

# cycle: revezar cores sem fim, limitado por islice
cores = cycle(["vermelho", "verde", "azul"])
print(list(islice(cores, 7)))
# ['vermelho', 'verde', 'azul', 'vermelho', 'verde', 'azul', 'vermelho']

count e cycle são infinitos; islice limita a quantidade e evita rodar sem fim.

Outra ferramenta muito usada é o chain, que junta vários iteráveis num só fluxo, como se concatenasse, mas sem construir uma lista grande na memória. Percorrer duas ou três listas em sequência com chain é mais eficiente do que somá-las numa terceira, porque nada novo é criado: o chain apenas passa de um iterável ao próximo à medida que você consome. Isso resume o espírito do itertools: fazer muito com pouca memória, tratando os dados como um fluxo preguiçoso.

islice: fatiar com preguiça

Você já conhece o fatiamento com colchetes em listas, mas ele exige uma sequência inteira na memória e não funciona em iteradores infinitos. O islice faz o fatiamento de qualquer iterável de forma preguiçosa: ele consome só o que precisa para entregar o pedaço pedido e para. É o que permite pegar os primeiros cinco itens de um count infinito, como nos exemplos, ou pular um trecho e pegar outro. Com fontes grandes ou infinitas, o islice é a maneira segura de fatiar sem estourar a memória.

from itertools import islice, chain

# chain: percorrer varias listas como um fluxo unico
semana = ["seg", "ter", "qua"]
fim = ["qui", "sex"]
for dia in chain(semana, fim):
    print(dia, end=" ")  # seg ter qua qui sex
print()

# islice com inicio e fim: pega do indice 2 ao 5
numeros = range(100)
print(list(islice(numeros, 2, 6)))  # [2, 3, 4, 5]

chain une iteráveis num fluxo; islice fatia por posição sem materializar tudo.

groupby: agrupar itens consecutivos

O groupby agrupa itens consecutivos que compartilham uma chave. Você passa o iterável e uma função que extrai a chave de cada item, e ele devolve grupos de vizinhos iguais. Há um detalhe crucial: o groupby só junta itens adjacentes, então ele não reúne ocorrências espalhadas. Se você quer agrupar todos os itens de cada categoria, precisa ordenar os dados por essa chave antes, para que os iguais fiquem lado a lado. Esquecer disso é o erro mais comum com groupby.

from itertools import groupby

pessoas = [
    {"nome": "Ana", "cidade": "SP"},
    {"nome": "Beto", "cidade": "SP"},
    {"nome": "Caio", "cidade": "RJ"},
    {"nome": "Duda", "cidade": "RJ"},
]

# Ja estao ordenados por cidade; agrupa por cidade:
por_cidade = groupby(pessoas, key=lambda p: p["cidade"])
for cidade, grupo in por_cidade:
    nomes = [p["nome"] for p in grupo]
    print(cidade, nomes)
# SP ['Ana', 'Beto'] / RJ ['Caio', 'Duda']

groupby junta vizinhos com a mesma chave; os dados precisam estar ordenados por ela.

Com count, cycle, chain, islice e groupby você já tem uma boa base do itertools, e o módulo traz muitas outras, para combinações, produtos e acumulações. O fio comum é a eficiência: iteradores preguiçosos que processam dados como fluxo, sem materializar tudo. Isso encerra o módulo de programação funcional. Você aprendeu a preferir funções puras e imutabilidade, a transformar e selecionar com map e filter, a acumular e especializar com reduce e partial, a memoizar com lru_cache e a manipular fluxos com o itertools. É um estilo que, bem usado, deixa o código mais claro e eficiente.

Teste rápido

Por que geralmente é preciso ordenar os dados antes de usar o groupby?

Perguntas frequentes

count e cycle não travam o programa por serem infinitos?
Só travariam se você tentasse materializar todos os itens, como chamar list direto neles. O jeito certo é combiná-los com algo que limite o consumo, como islice ou uma condição de parada num laço. Assim você aproveita a geração infinita pegando apenas os itens de que precisa, sem rodar sem fim.
Qual a vantagem do chain sobre somar listas com o operador de mais?
Somar listas cria uma terceira lista na memória com todos os itens. O chain apenas percorre os iteráveis em sequência, sem construir nada novo, passando de um ao próximo conforme você consome. Para iteráveis grandes, isso economiza memória; para poucos itens, a diferença é pequena e ambos servem.
islice é igual ao fatiamento com colchetes?
É parecido no efeito, mas funciona em qualquer iterável, inclusive infinitos, e é preguiçoso: consome só o necessário. O fatiamento com colchetes exige uma sequência já na memória, como uma lista. Quando a fonte é um iterador ou é grande demais para caber na memória, o islice é a ferramenta certa.
Posso reaproveitar um iterador do itertools depois de consumi-lo?
Não. Iteradores são consumidos uma vez: depois de percorrer, eles se esgotam. Se precisa passar pelos dados mais de uma vez, guarde-os numa lista ou gere o iterador de novo. Isso vale para todo o itertools e é uma diferença importante em relação a uma lista, que pode ser percorrida várias vezes.
O grupo que o groupby devolve é uma lista?
Não, é um iterador preguiçoso, e ele é válido só enquanto você não avança para o próximo grupo. Por isso, se quer guardar os itens de um grupo, converta-o em lista na hora, como fizemos no exemplo. Avançar no groupby antes de consumir o grupo atual faz você perder aqueles itens.
De onde importo as ferramentas do itertools?
Do módulo itertools da biblioteca padrão, por exemplo from itertools import count, cycle, chain, islice, groupby. Nada para instalar, e tudo roda no Playground do curso. O módulo tem muitas outras funções úteis, como combinations e product, que a documentação oficial detalha com exemplos.

Fontes

Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.