itertools.pairwise: compara elementos vecinos

Publicado el: 31/08/2026
Tempo de leitura: 4 minutos
Persona programando y analizando datos con Python

itertools.pairwise() recorre un iterable y produce pares formados por elementos consecutivos. En lugar de administrar índices manualmente, recibes directamente (anterior, actual), lo que mejora la legibilidad y reduce errores en los límites de la secuencia.

La función fue incorporada en Python 3.10 y resulta útil en series temporales, validación de secuencias, detección de transiciones, geometría, registros, eventos y procesamiento de datos. Es lazy: genera cada par bajo demanda y no necesita copiar toda la entrada.

Cómo funciona pairwise

from itertools import pairwise

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

El resultado contiene (10, 14), (14, 13) y (13, 20). Un iterable con menos de dos elementos no produce pares.

Calcular diferencias consecutivas

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

Este patrón aparece en métricas, precios, sensores y cualquier conjunto de datos ordenado en el tiempo. El código comunica la intención con claridad: comparar cada valor con el siguiente.

Detectar cambios de estado

estados = ["offline", "offline", "online", "online", "error"]
for anterior, actual in pairwise(estados):
    if anterior != actual:
        print(f"cambio: {anterior} -> {actual}")

En observabilidad, este enfoque permite localizar transiciones sin guardar manualmente una variable con el estado anterior.

Validar secuencias crecientes

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

La combinación con all() mantiene la evaluación lazy y se detiene al encontrar la primera violación, lo que puede ahorrar trabajo en secuencias grandes.

Calcular intervalos entre fechas

from datetime import date

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

El mismo principio funciona con timestamps, versiones, posiciones geográficas, etapas de un proceso y puntos de control.

Construir segmentos

Cuando una lista representa puntos de una ruta, cada par consecutivo define un segmento.

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

La solución es más clara que range(len(puntos) - 1) y evita accesos repetidos por índice.

Pairwise frente a zip y slicing

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

Para listas pequeñas, zip con slicing funciona. Sin embargo, el slice crea otra lista y el patrón no se aplica directamente a generadores. Pairwise acepta cualquier iterable y conserva el comportamiento lazy.

Pairwise frente a tee

Antes de Python 3.10 era común implementar esta operación con itertools.tee(). Esa receta sigue siendo válida para compatibilidad, pero pairwise expresa mejor la intención.

from itertools import tee

def pairwise_compatible(iterable):
    primero, segundo = tee(iterable)
    next(segundo, None)
    return zip(primero, segundo)

tee puede almacenar elementos temporalmente si sus iteradores avanzan a ritmos diferentes. Pairwise gestiona internamente el estado necesario para este caso concreto.

Uso con generadores

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

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

No se crea una lista con un millón de elementos. Esta propiedad hace que pairwise sea adecuado para archivos, streams, cursores de bases de datos y pipelines extensos.

Detectar huecos

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

El patrón sirve para números de secuencia, lotes, offsets, facturas y registros de eventos.

Combinar pairwise con enumerate

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

Con inicio en uno, el índice corresponde a la posición del segundo elemento del par en la secuencia original. Conviene documentar esa convención.

Secuencias circulares

Pairwise no conecta automáticamente el último elemento con el primero. Para representar un ciclo, agrega o encadena explícitamente el primer elemento.

from itertools import chain

colores = ["rojo", "verde", "azul"]
pares_circulares = pairwise(chain(colores, colores[:1]))

Con un generador, conserva solo el primer elemento y encadénalo al final, considerando también el caso de un iterable vacío.

No modifiques la colección durante el recorrido

Cambiar una lista mientras pairwise la consume puede producir resultados inesperados. Es preferible generar una nueva secuencia o aplicar transformaciones antes de construir los pares.

Tratar datos ausentes

Las series reales suelen contener None, NaN o registros inválidos. Define si deseas filtrar, cortar el segmento o conservar el par para registrar el problema.

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

Filtrar cambia la vecindad: 10 y 12 pasan a ser consecutivos. Esa decisión puede ser correcta en un dominio y engañosa en otro.

Rendimiento

Pairwise tiene coste lineal y usa poca memoria adicional. Como no materializa todos los pares, suele ser eficiente. Aun así, la operación ejecutada para cada par puede dominar el tiempo total, especialmente si realiza entrada y salida.

Errores frecuentes

  • Esperar salida de un iterable con un solo elemento.
  • Suponer que el último elemento se conecta con el primero.
  • Consumir un generador antes de entregarlo a pairwise.
  • Ignorar valores ausentes que cambian la semántica de vecindad.
  • Usar pairwise cuando se necesitan ventanas de tres o más elementos.

Ventanas mayores

Pairwise crea ventanas de exactamente dos elementos. Para ventanas deslizantes mayores, utiliza una receta con deque o iteradores alineados. itertools.batched produce bloques no superpuestos, una operación diferente.

Pruebas recomendadas

Prueba entrada vacía, un elemento, dos elementos, valores repetidos, datos inválidos y generadores grandes. Las pruebas basadas en propiedades son útiles para monotonicidad y detección de huecos.

Buenas prácticas

Confirma el orden de los datos, conserva la evaluación lazy cuando sea posible y usa nombres descriptivos como anterior y actual. Continúa con las guías de Academify sobre itertools en Python, generadores, list comprehensions y funciones en Python.

Conclusión

itertools.pairwise es una herramienta pequeña que resuelve un patrón frecuente de forma elegante. Elimina índices manuales, acepta cualquier iterable y combina bien con all, comprehensions y pipelines lazy. Cuando necesites comparar vecinos, detectar transiciones o calcular diferencias, pairwise debería estar entre tus primeras opciones.

Fuentes externas

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Carpetas y directorios para contextlib.chdir en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    contextlib.chdir: restaura directorios automáticamente

    Aprende contextlib.chdir en Python para cambiar directorios temporalmente, restaurar rutas y crear pruebas confiables sin errores de estado global.

    Ler mais

    Tempo de leitura: 6 minutos
    03/09/2026
    Monitoreo de rendimiento y ejecución de código Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    sys.monitoring: instrumentación de bajo overhead

    Aprende sys.monitoring en Python para instrumentar ejecución con bajo overhead, eventos selectivos, callbacks y observabilidad segura.

    Ler mais

    Tempo de leitura: 6 minutos
    03/09/2026
    Desarrollador organizando datos con operator.attrgetter en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    operator.attrgetter: ordena objetos por atributos

    Aprende operator.attrgetter en Python para ordenar, agrupar y transformar objetos por atributos simples o anidados con código claro.

    Ler mais

    Tempo de leitura: 4 minutos
    02/09/2026
    Programación asíncrona con asyncio.Runner en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    asyncio.Runner: reutiliza el event loop con seguridad

    Aprende asyncio.Runner en Python para reutilizar el event loop, controlar contexto, señales, debug, cancelación y cierre asíncrono seguro.

    Ler mais

    Tempo de leitura: 7 minutos
    02/09/2026
    Compresión de datos binarios con Zstandard en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: Zstandard con streams y diccionarios

    Aprende compression.zstd en Python para comprimir datos con Zstandard, streaming, diccionarios y límites seguros.

    Ler mais

    Tempo de leitura: 7 minutos
    01/09/2026
    Aplicación Python empaquetada como archivo ejecutable con zipapp
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    zipapp en Python: crea apps ejecutables

    Aprende zipapp en Python para empaquetar aplicaciones como archivos pyz ejecutables, incluir dependencias y distribuirlas con seguridad.

    Ler mais

    Tempo de leitura: 5 minutos
    01/09/2026