itertools.groupby: agrupa datos ordenados correctamente

Publicado el: 30/08/2026
Tempo de leitura: 2 minutos
A person reads 'Python for Unix and Linux System Administration' indoors.

itertools.groupby() agrupa elementos consecutivos que producen la misma clave. Es lazy, consume la entrada solo cuando hace falta y puede procesar streams grandes sin cargar todos los datos en memoria. Su comportamiento no es igual al GROUP BY de SQL: claves iguales que no son adyacentes generan grupos separados.

Esta guía explica ordenación previa, subiteradores compartidos, agregaciones streaming, objetos, grupos anidados y errores frecuentes.

Ejemplo básico

from itertools import groupby

valores = [1, 1, 2, 2, 2, 3]
for clave, grupo in groupby(valores):
    print(clave, list(grupo))

Cada secuencia consecutiva de valores iguales se convierte en un grupo.

La adyacencia es la regla principal

valores = [1, 2, 1]
print([(clave, list(grupo)) for clave, grupo in groupby(valores)])

El valor 1 aparece dos veces porque está separado. Ordena primero cuando quieras reunir todas las claves iguales.

Ordenar con la misma clave

registros.sort(key=lambda item: item["categoria"])
for categoria, grupo in groupby(registros, key=lambda item: item["categoria"]):
    elementos = list(grupo)
    procesar(categoria, elementos)

La clave de ordenación y la de agrupación deben representar la misma regla.

Los grupos comparten el iterador

Cada grupo es un subiterador conectado al iterador principal. Al avanzar a la siguiente clave, el grupo anterior deja de estar disponible. Materialízalo de inmediato si necesitas conservarlo.

for clave, grupo in groupby(datos, key=obtener_clave):
    elementos = list(grupo)
    guardar(clave, elementos)

Agregación streaming

for categoria, grupo in groupby(registros, key=lambda fila: fila.categoria):
    total = sum(fila.importe for fila in grupo)
    print(categoria, total)

El grupo se consume directamente y mantiene bajo el uso de memoria.

Contar sin crear listas

for clave, grupo in groupby(datos, key=obtener_clave):
    cantidad = sum(1 for _ in grupo)
    print(clave, cantidad)

Agrupar objetos

from operator import attrgetter

pedidos.sort(key=attrgetter("cliente_id"))
for cliente_id, grupo in groupby(pedidos, key=attrgetter("cliente_id")):
    procesar_pedidos(cliente_id, grupo)

attrgetter puede expresar la intención mejor que varias lambdas repetidas.

Entradas ya ordenadas

Resultados SQL con ORDER BY, archivos ordenados y streams monotónicos son casos ideales. groupby permite agregarlos de forma incremental.

Diccionario frente a groupby

Un diccionario de listas agrupa sin importar el orden, pero conserva todos los elementos. groupby usa poca memoria, aunque necesita claves adyacentes.

Normalización de texto

nombres.sort(key=str.casefold)
for clave, grupo in groupby(nombres, key=str.casefold):
    print(clave, list(grupo))

Usa la misma normalización al ordenar y agrupar. Para texto humano puede ser necesario considerar locale.

Agrupación anidada

filas.sort(key=lambda fila: (fila.pais, fila.ciudad))
for pais, grupo_pais in groupby(filas, key=lambda fila: fila.pais):
    filas_pais = list(grupo_pais)
    for ciudad, grupo_ciudad in groupby(filas_pais, key=lambda fila: fila.ciudad):
        procesar(pais, ciudad, grupo_ciudad)

El grupo exterior se materializa porque todos los subgrupos comparten el iterador subyacente.

Errores comunes

  • Esperar que claves iguales no adyacentes se unan.
  • Ordenar y agrupar con claves incompatibles.
  • Guardar el subiterador para consumirlo después.
  • Convertir todos los grupos en listas sin necesidad.
  • Usar una función de clave con efectos secundarios.

Buenas prácticas

Documenta el requisito de orden, mantén las funciones de clave puras, consume cada grupo antes de avanzar y materializa solo cuando sea necesario. Consulta también las guías internas de itertools en Python y itertools.pairwise.

Conclusión

itertools.groupby es ideal para segmentar secuencias ordenadas y crear agregaciones de bajo consumo de memoria. Comprender la adyacencia y los iteradores compartidos evita resultados incorrectos.

Fuentes externas

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Icono de compresión de archivos ZIP
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    ZipInfo.compress_level: controla la compresión ZIP

    Aprende ZipInfo.compress_level en Python para elegir compresión por archivo y equilibrar tamaño, CPU, latencia y compatibilidad.

    Ler mais

    Tempo de leitura: 5 minutos
    24/10/2026
    Código binario que representa bytearray.resize en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    bytearray.resize: redimensiona buffers con seguridad

    Aprende bytearray.resize en Python para ampliar y reducir búferes con límites, memoryview y compatibilidad.

    Ler mais

    Tempo de leitura: 5 minutos
    24/10/2026
    Código Python en un portátil para filtrar valores None
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    operator.is_none: filtra None sin perder falsy

    Aprende operator.is_none e is_not_none para filtrar None sin eliminar valores falsy válidos en Python.

    Ler mais

    Tempo de leitura: 4 minutos
    23/10/2026
    Código Python en un portátil para crear dataclasses dinámicas
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    make_dataclass decorator: transforma dataclasses

    Aprende a usar el parámetro decorator de make_dataclass para validar, registrar y transformar dataclasses dinámicas en Python.

    Ler mais

    Tempo de leitura: 6 minutos
    23/10/2026
    Estructura de código y XML para canonicalización con Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    ElementTree canonicalize: normaliza XML en Python

    Aprende ElementTree canonicalize en Python para comparar XML, generar hashes estables y controlar namespaces, espacios y comentarios.

    Ler mais

    Tempo de leitura: 5 minutos
    22/10/2026
    Código Python en una pantalla
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    T-strings y templatelib: interpolación estructurada

    Aprende t-strings y string.templatelib en Python para interpolación estructurada, renderizado seguro, logs y procesamiento personalizado.

    Ler mais

    Tempo de leitura: 6 minutos
    22/10/2026