itertools.pairwise: compare elementos vizinhos

Publicado em: 31/08/2026
Tempo de leitura: 4 minutos
Pessoa programando e analisando dados em Python

itertools.pairwise() percorre um iterável e produz pares formados por elementos consecutivos. Em vez de trabalhar com índices, você recebe diretamente (item_atual, item_seguinte), o que deixa o código mais legível e reduz erros de limite.

A função foi adicionada ao Python 3.10 e é especialmente útil em análise de séries temporais, validação de sequências, cálculo de diferenças, detecção de transições, geometria, logs e processamento de eventos. Ela é lazy: os pares são gerados sob demanda, sem copiar toda a coleção.

Como pairwise funciona

from itertools import pairwise

valores = [10, 14, 13, 20]
for anterior, atual in pairwise(valores):
    print(anterior, atual)

O resultado contém os pares (10, 14), (14, 13) e (13, 20). Uma sequência com menos de dois itens não produz nenhum par.

Calcular diferenças consecutivas

from itertools import pairwise

temperaturas = [21.2, 22.0, 21.7, 23.1]
diferencas = [b - a for a, b in pairwise(temperaturas)]
print(diferencas)

Esse padrão aparece em métricas, preços, sensores e qualquer dado ordenado no tempo. O código expressa a intenção diretamente: comparar cada valor com o próximo.

Detectar mudanças de estado

estados = ["offline", "offline", "online", "online", "erro"]

for anterior, atual in pairwise(estados):
    if anterior != atual:
        print(f"mudança: {anterior} -> {atual}")

Em sistemas de observabilidade, esse formato ajuda a localizar transições sem armazenar manualmente uma variável anterior.

Validar sequências crescentes

def estritamente_crescente(valores):
    return all(a < b for a, b in pairwise(valores))

O uso de all() mantém o processamento lazy e interrompe assim que encontra uma violação. Isso pode economizar trabalho em sequências grandes.

Encontrar intervalos em datas

from datetime import date
from itertools import pairwise

datas = [date(2026, 1, 3), date(2026, 1, 8), date(2026, 1, 10)]
intervalos = [(b - a).days for a, b in pairwise(datas)]

O mesmo raciocínio vale para timestamps, versões, posições geográficas e etapas de um processo.

Construir segmentos

Quando uma lista representa pontos de uma rota, cada par consecutivo define um segmento.

pontos = [(0, 0), (3, 4), (6, 4)]
segmentos = list(pairwise(pontos))

Isso evita o padrão mais verboso range(len(pontos) - 1) e elimina acessos repetidos por índice.

Comparação com zip e slicing

pares = zip(valores, valores[1:])

Para listas pequenas, zip com slicing funciona. Porém, o slice cria uma nova lista e não se aplica diretamente a geradores. pairwise aceita qualquer iterável e preserva o comportamento lazy.

Comparação com tee

Antes do Python 3.10, uma implementação comum usava itertools.tee(). Ela continua útil para compatibilidade, mas pairwise é mais clara e comunica melhor a intenção.

from itertools import tee

def pairwise_compativel(iterable):
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)

tee pode precisar armazenar itens temporariamente quando os iteradores avançam em ritmos diferentes. No uso de pairwise, esse detalhe já é tratado pela biblioteca.

Uso com geradores

def leituras():
    for valor in range(1_000_000):
        yield valor

for a, b in pairwise(leituras()):
    if b - a != 1:
        break

Nenhuma lista de um milhão de itens é criada. Essa característica torna a função adequada para arquivos, streams e pipelines de dados.

Detectar lacunas

ids = [100, 101, 102, 106, 107]
for a, b in pairwise(ids):
    if b != a + 1:
        print("lacuna entre", a, "e", b)

Esse padrão é útil para validar numeração, lotes, offsets e sequências de eventos.

Pairwise com enumerate

for indice, (a, b) in enumerate(pairwise(valores), start=1):
    print(indice, a, b)

O índice representa a posição do segundo elemento no par quando o início é 1. Documente essa convenção para evitar confusão.

Sequências circulares

Pairwise não conecta automaticamente o último item ao primeiro. Para ciclos, acrescente explicitamente o primeiro elemento.

from itertools import chain

cores = ["vermelho", "verde", "azul"]
pares_circulares = pairwise(chain(cores, cores[:1]))

Em geradores, você pode guardar apenas o primeiro item e encadeá-lo ao final, tomando cuidado com iteráveis vazios.

Evite modificar a coleção durante o percurso

Alterar a lista enquanto pairwise a percorre pode produzir resultados inesperados. Prefira gerar uma nova coleção ou aplicar transformações antes de criar os pares.

Tratamento de dados ausentes

Em séries reais, valores None ou inválidos exigem uma política explícita. Você pode filtrar antes, interromper o segmento ou manter o par para registrar a ausência.

dados = [10, None, 12, 15]
validos = (x for x in dados if x is not None)
print(list(pairwise(validos)))

Filtrar altera a noção de vizinhança: 10 e 12 tornam-se consecutivos. Em alguns domínios isso é correto; em outros, o valor ausente precisa quebrar a série.

Desempenho

Pairwise tem custo linear em relação ao número de itens e memória adicional pequena. Como não materializa todos os pares, costuma ser uma escolha eficiente. Ainda assim, a função aplicada a cada par pode dominar o tempo total.

Erros comuns

  • Esperar um par para uma sequência com um único elemento.
  • Assumir que o último item será ligado ao primeiro.
  • Consumir um gerador antes de passá-lo para pairwise.
  • Ignorar valores ausentes que mudam a semântica da vizinhança.
  • Usar pairwise quando o problema exige janelas de três ou mais elementos.

Janelas maiores

Pairwise cria apenas janelas de tamanho dois. Para janelas maiores, use uma combinação de iteradores, deque ou itertools.batched quando blocos não sobrepostos forem aceitáveis. Janelas deslizantes e lotes são conceitos diferentes.

Boas práticas

Garanta que os dados estejam na ordem correta, mantenha a transformação lazy sempre que possível e escolha nomes como anterior e atual. Para aprofundar, leia os guias da Academify sobre itertools no Python, generators, list comprehensions e funções em Python.

Conclusão

itertools.pairwise é uma ferramenta pequena que resolve um padrão recorrente com clareza. Ela elimina índices manuais, funciona com qualquer iterável e combina bem com all, comprehensions e pipelines lazy. Sempre que você precisar comparar vizinhos, detectar transições ou calcular deltas, pairwise deve estar entre as primeiras opções.

Fontes externas

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    High-angle view of woman coding on a laptop, with a Python book nearby. Ideal for programming and tech content.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    types.new_class no Python: classes dinâmicas

    Aprenda types.new_class no Python para gerar classes dinâmicas com metaclasses, namespaces preparados, herança e metadados corretos.

    Ler mais

    Tempo de leitura: 4 minutos
    30/08/2026
    Detailed view of computer code highlighting syntax in colors on a screen.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    partialmethod: crie métodos especializados no Python

    Aprenda partialmethod no Python para criar métodos especializados com binding correto, menos wrappers e APIs de domínio mais claras.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    A detailed image of a reticulated python showcasing its patterned scales and intricate skin texture.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    inspect.getmembers_static: liste atributos sem executar

    Use inspect.getmembers_static no Python para listar atributos sem executar properties, descriptors ou resolução dinâmica indesejada.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    Close-up of a python snake curled up, showcasing its detailed scales.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    DynamicClassAttribute: descriptors e acesso dinâmico

    Entenda DynamicClassAttribute no Python, descriptors, acesso por classe e instância, metaclasses, Enum e introspecção segura.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    A laptop screen showing a code editor with visible programming code in a dimly lit environment.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    UserList no Python: listas customizadas

    Aprenda UserList no Python para criar listas customizadas com validação, normalização, regras de mutação e APIs previsíveis.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    Close-up of a person underlining text in a dictionary on a desk with a laptop.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    UserDict no Python: dicionários customizados

    Aprenda UserDict no Python para criar dicionários customizados com validação, normalização, composição e APIs previsíveis.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026