Quando você precisa iterar sobre dados de forma eficiente em Python, o módulo itertools é a ferramenta mais poderosa da biblioteca padrão. Ele fornece funções que criam iteradores para loops eficientes, combinando conceitos de programação funcional com a elegância do Python.

Neste guia completo, você vai aprender desde os iteradores mais simples até combinações avançadas, com exemplos práticos de código que vão transformar a forma como você escreve loops e processa dados em Python.

O Que é o Módulo itertools?

O itertools é um módulo da biblioteca padrão do Python que implementa uma série de funções iteradoras inspiradas em construções da programação funcional, como Haskell e APL. Ele é descrito na documentação oficial como um "kit de ferramentas para criar e combinar iteradores".

A principal filosofia do itertools é fornecer blocos de construção que podem ser combinados para resolver problemas complexos de iteração de forma elegante e eficiente. Todas as funções do itertools retornam iteradores (ou seja, trabalham com lazy evaluation), o que significa que consomem pouca memória mesmo com grandes volumes de dados. Isso é especialmente importante em cenários de big data e processamento de streams.

Fonte: Documentação Oficial do Python - itertools

Importando o Módulo

O itertools já vem instalado com Python, então você só precisa importá-lo. Não é necessário instalar nada adicional via pip:

import itertools

# Ou importar funções específicas
from itertools import chain, cycle, count, product

Iteradores Infinitos

Os iteradores infinitos geram valores continuamente, sem um limite definido. São úteis para simular sequências infinitas, contadores e repetições. Por trabalharem com lazy evaluation, você pode usá-los sem preocupação com memória, mesmo que teoricamente gerem valores para sempre.

count(start=0, step=1)

Gera números consecutivos a partir de um valor inicial com um passo definido. Excelente para criar contadores ou índices automáticos:

from itertools import count

for i in count(10, 2):
    if i > 20:
        break
    print(i, end=" ")  # 10 12 14 16 18 20

cycle(iterable)

Repete um iterável infinitamente. Muito usado para alternar entre valores fixos:

from itertools import cycle

cores = cycle(['vermelho', 'verde', 'azul'])
for i in range(6):
    print(next(cores), end=" ")  # vermelho verde azul vermelho verde azul

repeat(object, times=None)

Repete um objeto um número específico de vezes. Sem o parâmetro times, repete infinitamente:

from itertools import repeat

for valor in repeat(42, 5):
    print(valor, end=" ")  # 42 42 42 42 42

Fonte: Real Python - Infinite Iterators in itertools

Iteradores de Combinação

Estes iteradores geram todas as combinações ou permutações possíveis de um conjunto de elementos. São fundamentais em problemas de matemática, estatística e otimização, permitindo explorar espaços de busca completos sem escrever múltiplos loops aninhados manualmente.

product(*iterables, repeat=1)

Calcula o produto cartesiano entre dois ou mais iteráveis. Equivale a loops aninhados:

from itertools import product

for item in product([1, 2], ['a', 'b']):
    print(item, end=" ")  # (1, 'a') (1, 'b') (2, 'a') (2, 'b')

for item in product([1, 2], repeat=2):
    print(item, end=" ")  # (1, 1) (1, 2) (2, 1) (2, 2)

permutations(iterable, r=None)

Gera todas as permutações possíveis de r elementos. A ordem dos elementos importa:

from itertools import permutations

for item in permutations([1, 2, 3], 2):
    print(item, end=" ")  # (1, 2) (1, 3) (2, 1) (2, 3) (3, 1) (3, 2)

combinations(iterable, r)

Gera todas as combinações de r elementos. Diferente de permutations, a ordem dos elementos NÃO importa:

from itertools import combinations

for item in combinations([1, 2, 3], 2):
    print(item, end=" ")  # (1, 2) (1, 3) (2, 3)

combinations_with_replacement(iterable, r)

Similar a combinations, mas permite que elementos se repitam dentro da mesma combinação:

from itertools import combinations_with_replacement

for item in combinations_with_replacement([1, 2, 3], 2):
    print(item, end=" ")  # (1, 1) (1, 2) (1, 3) (2, 2) (2, 3) (3, 3)

Fonte: GeeksforGeeks - Python itertools Module

Fonte: Programiz - Python itertools Module

Iteradores de Terminação

Estes iteradores consomem um ou mais iteráveis de entrada e produzem um resultado transformado.

chain(*iterables)

Concatena múltiplos iteráveis em uma única sequência. Perfeito para percorrer várias coleções como se fossem uma só:

from itertools import chain

resultado = list(chain([1, 2], [3, 4], [5, 6]))
print(resultado)  # [1, 2, 3, 4, 5, 6]

accumulate(iterable, func=operator.add)

Retorna valores acumulados sucessivamente. Por padrão usa soma, mas aceita qualquer função binária:

from itertools import accumulate
import operator

print(list(accumulate([1, 2, 3, 4, 5])))  # [1, 3, 6, 10, 15]
print(list(accumulate([1, 2, 3, 4, 5], operator.mul)))  # [1, 2, 6, 24, 120]

groupby(iterable, key=None)

Agrupa elementos consecutivos com base em uma chave. Os dados precisam estar ordenados pela chave de agrupamento:

from itertools import groupby

dados = [('ana', 'A'), ('joao', 'A'), ('maria', 'B'), ('pedro', 'B')]
dados.sort(key=lambda x: x[1])

for letra, grupo in groupby(dados, key=lambda x: x[1]):
    print(f"{letra}: {[nome for nome, _ in grupo]}")

islice(iterable, start, stop, step=1)

Fatia um iterador como faria com listas, mas sem criar listas intermediárias:

from itertools import islice

resultado = list(islice(range(100), 2, 8, 2))
print(resultado)  # [2, 4, 6]

compress(data, selectors)

Filtra elementos de data com base nos valores booleanos de selectors:

from itertools import compress

dados = ['A', 'B', 'C', 'D', 'E']
seletores = [1, 0, 1, 0, 1]
print(list(compress(dados, seletores)))  # ['A', 'C', 'E']

dropwhile e takewhile

dropwhile descarta elementos enquanto a condição for True e depois retorna o restante. takewhile faz o oposto:

from itertools import dropwhile, takewhile

numeros = [1, 2, 3, 4, 5, 1, 2, 3]

print(list(dropwhile(lambda x: x < 3, numeros)))  # [3, 4, 5, 1, 2, 3]
print(list(takewhile(lambda x: x < 3, numeros)))  # [1, 2]

pairwise (Python 3.10+)

Retorna tuplas sobrepostas de elementos consecutivos. Ótimo para comparar elementos adjacentes:

from itertools import pairwise

print(list(pairwise([1, 2, 3, 4])))  # [(1, 2), (2, 3), (3, 4)]

starmap(func, iterable)

Similar a map, mas desempacota cada elemento como argumentos individuais:

from itertools import starmap

pares = [(2, 3), (4, 5), (6, 7)]
print(list(starmap(lambda x, y: x * y, pares)))  # [6, 20, 42]

zip_longest(*iterables, fillvalue=None)

Similar a zip, mas continua até o iterável mais longo, preenchendo valores faltantes:

from itertools import zip_longest

a = [1, 2, 3]
b = ['a', 'b']
print(list(zip_longest(a, b, fillvalue='-')))  # [(1, 'a'), (2, 'b'), (3, '-')]

Fonte: Python Functional Programming HOWTO - itertools

Casos de Uso Reais

1. Agrupamento de Logs com groupby

from itertools import groupby

logs = [
    ('2026-05-01', 'ERRO', 'Falha na conexão'),
    ('2026-05-01', 'INFO', 'Servidor iniciado'),
    ('2026-05-02', 'ERRO', 'Timeout excedido'),
    ('2026-05-02', 'INFO', 'Backup concluído'),
]

logs.sort(key=lambda x: x[1])
for nivel, grupo in groupby(logs, key=lambda x: x[1]):
    print(f"{nivel}: {len(list(grupo))} ocorrências")

2. Geração de Combinações com product

from itertools import product
import string

caracteres = string.ascii_lowercase + string.digits
senhas = product(caracteres, repeat=4)
# Útil para gerar combinações para testes

3. Análise Financeira com accumulate

from itertools import accumulate

precos = [100, 102, 105, 103, 107, 110]
variacao = [precos[i] - precos[i-1] for i in range(1, len(precos))]
print(list(accumulate(variacao)))

4. Leitura Eficiente de Arquivos com islice

from itertools import islice

def ler_linhas_especificas(arquivo, inicio, fim):
    with open(arquivo, 'r') as f:
        return list(islice(f, inicio, fim))

Performance e Eficiência

Uma das maiores vantagens do itertools é a eficiência de memória. Como todas as funções retornam iteradores com lazy evaluation, você pode processar milhões de elementos sem consumir memória proporcionalmente.

import sys
from itertools import count

contador = count()
print(sys.getsizeof(contador))  # 48 bytes (aprox.)

As funções do itertools são implementadas em C, o que as torna significativamente mais rápidas que implementações equivalentes em Python puro. Para entender melhor como iteradores e generators funcionam internamente, veja nosso guia completo sobre Python Generators. E para dominar expressões compactas que complementam o itertools, confira nosso tutorial de List Comprehension em Python.

Fonte: Stack Overflow - Why is itertools important?

Combinando itertools com Generators

O itertools funciona perfeitamente com generators. Você pode combinar ambas as técnicas para criar pipelines de processamento extremamente eficientes:

from itertools import islice, count

def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

fib_gen = fibonacci()
primeiros_10 = list(islice(fib_gen, 10))
print(primeiros_10)  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Dicas e Boas Práticas

  • Importe funções específicas - Em vez de importar todo o módulo, importe apenas as funções necessárias para manter o código mais limpo.
  • Prefira itertools a loops manuais - As funções do itertools são implementadas em C e são significativamente mais rápidas que loops Python equivalentes.
  • Mantenha a lazy evaluation - Converter um iterador em lista prematuramente perde o benefício de memória. Mantenha os dados como iteradores até precisar deles.
  • Combine itertools com functools e operators - Use operator.add, operator.mul etc. com accumulate e starmap para código mais expressivo.
  • Considere o more-itertools - O pacote de terceiros more-itertools estende o itertools com funções adicionais como chunked, windowed e padded.

Fonte: DataCamp - Python itertools Tutorial

Conclusão

O módulo itertools do Python é uma ferramenta indispensável para qualquer desenvolvedor que trabalha com dados. Suas funções para manipulação eficiente de iteradores permitem escrever código mais limpo, rápido e com menor consumo de memória.

Dominar o itertools eleva significativamente a qualidade do seu código Python, especialmente quando combinado com generators e list comprehensions. Os conceitos de lazy evaluation e combinação de iteradores são fundamentais para programação funcional em Python e para escrever código mais idiomático e performático.

Continue explorando os guias gratuitos do Universo Python para aprofundar seus conhecimentos sobre iteradores, generators e programação funcional, e se tornar um desenvolvedor Python mais completo e eficiente!