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

    A person typing on a laptop with a Python programming book visible, capturing technology and learning.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    types.new_class en Python: clases dinámicas

    Aprende types.new_class en Python para generar clases dinámicas con metaclases, namespaces preparados, herencia y metadatos correctos.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    High-angle view of woman coding on a laptop, with a Python book nearby. Ideal for programming and tech content.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    partialmethod: crea métodos especializados en Python

    Aprende partialmethod en Python para métodos especializados con binding correcto, menos wrappers y APIs de dominio más claras.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    Close-up view of a computer screen displaying code in a software development environment.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    inspect.getmembers_static: atributos sin ejecutar

    Usa inspect.getmembers_static en Python para listar atributos sin ejecutar properties, descriptors ni resolución dinámica no deseada.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    Close-up view of a computer screen displaying code in a software development environment.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    DynamicClassAttribute: descriptors y acceso dinámico

    Entiende DynamicClassAttribute en Python, descriptors, acceso por clase e instancia, metaclases, Enum e introspección segura.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    Vibrant close-up of artistically decorated acoustic guitars with floral patterns.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    UserList en Python: secuencias personalizadas

    Aprende UserList en Python para crear secuencias personalizadas con validación, normalización, mutaciones y APIs predecibles.

    Ler mais

    Tempo de leitura: 2 minutos
    30/08/2026
    Close-up of a laptop screen with code and a coffee mug, perfect for tech abstract themes.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    UserDict en Python: mappings personalizados

    Aprende UserDict en Python para crear mappings personalizados con validación, normalización, composición y mutaciones predecibles.

    Ler mais

    Tempo de leitura: 2 minutos
    30/08/2026