itertools es un módulo de la biblioteca estándar de Python que reúne herramientas para trabajar con iteradores de forma eficiente. Permite combinar secuencias, generar valores infinitos, agrupar elementos, crear combinaciones y evitar listas temporales innecesarias. Su mayor ventaja es que muchas funciones producen resultados bajo demanda, lo que reduce memoria y facilita construir flujos de procesamiento.
Qué es un iterador
Un iterador entrega un elemento cada vez y recuerda su posición. Las listas pueden recorrerse muchas veces, mientras que un iterador suele consumirse. Comprender esta diferencia ayuda a evitar resultados vacíos después de una primera pasada.
iterador = iter([10, 20, 30])
print(next(iterador))
print(next(iterador))Para reforzar colecciones e iteración, revisa la guía de listas en Python.
Importar itertools
El módulo no necesita instalación:
import itertoolsTambién puedes importar funciones concretas:
from itertools import chain, count, combinationsLa documentación oficial de itertools agrupa las herramientas en iteradores infinitos, combinatorios y terminadores sobre iterables.
count para secuencias numéricas
count genera números sin final hasta que el consumidor se detiene:
from itertools import count
for numero in count(start=10, step=5):
print(numero)
if numero >= 30:
breakSiempre limita un iterador infinito con break, islice u otra condición.
cycle para repetir elementos
cycle repite una secuencia indefinidamente:
from itertools import cycle, islice
colores = cycle(["rojo", "verde", "azul"])
print(list(islice(colores, 7)))Es útil para asignar estilos, turnos o recursos de forma circular. Recuerda que necesita conservar una copia de los elementos vistos para poder repetirlos.
repeat para reutilizar un valor
repeat produce el mismo objeto varias veces:
from itertools import repeat
for mensaje in repeat("procesando", 3):
print(mensaje)También puede combinarse con map cuando una función necesita un argumento constante.
chain para unir iterables
chain recorre varios iterables como si fueran uno:
from itertools import chain
enero = [10, 20]
febrero = [30, 40]
marzo = [50]
for venta in chain(enero, febrero, marzo):
print(venta)No crea primero una lista combinada. Esto es útil cuando las entradas son grandes o generadores.
chain.from_iterable
Cuando ya tienes una colección de colecciones:
grupos = [[1, 2], [3, 4], [5]]
planos = chain.from_iterable(grupos)
print(list(planos))Evita bucles anidados simples y comunica claramente la intención de aplanar un nivel.
islice para limitar iteradores
islice aplica una lógica parecida al slicing sin exigir una secuencia completa:
from itertools import islice
primeros = islice(range(1_000_000), 10, 20, 2)
print(list(primeros))Es especialmente útil con archivos, generadores e iteradores infinitos.
combinations y permutations
combinations genera grupos sin considerar el orden:
from itertools import combinations
personas = ["Ana", "Luis", "Marta"]
print(list(combinations(personas, 2)))permutations sí considera el orden:
from itertools import permutations
print(list(permutations([1, 2, 3], 2)))El número de resultados puede crecer muy rápido. Evita convertir grandes combinaciones en una lista. Itera y detente cuando encuentres lo necesario.
product para producto cartesiano
product combina cada elemento de un iterable con todos los del otro:
from itertools import product
tamanos = ["S", "M"]
colores = ["negro", "blanco"]
for variante in product(tamanos, colores):
print(variante)Puede usarse en pruebas parametrizadas, configuraciones y generación de casos.
accumulate para resultados progresivos
accumulate genera acumulados:
from itertools import accumulate
ventas = [100, 50, 75]
print(list(accumulate(ventas)))También acepta una función, por ejemplo max, para producir máximos acumulados.
groupby y el requisito del orden
groupby agrupa elementos consecutivos con la misma clave:
from itertools import groupby
registros = [
{"tipo": "A", "valor": 1},
{"tipo": "A", "valor": 2},
{"tipo": "B", "valor": 3},
]
for tipo, grupo in groupby(registros, key=lambda item: item["tipo"]):
print(tipo, list(grupo))Si los registros no están ordenados por la misma clave, un tipo puede aparecer en varios grupos. Ordena antes cuando necesites agrupación global.
tee para duplicar un iterador
tee crea iteradores independientes a partir de uno:
from itertools import tee
origen = iter([1, 2, 3])
a, b = tee(origen, 2)
print(list(a))
print(list(b))Internamente necesita almacenar temporalmente valores cuando una copia avanza más que otra. Si la diferencia es enorme, el consumo de memoria puede crecer.
zip_longest para longitudes diferentes
La función zip termina con el iterable más corto. zip_longest continúa y completa valores ausentes:
from itertools import zip_longest
nombres = ["Ana", "Luis", "Marta"]
notas = [9, 8]
for nombre, nota in zip_longest(nombres, notas, fillvalue="sin nota"):
print(nombre, nota)La guía de zip en Python explica la función incorporada y el desempaquetado.
Integrar itertools con funciones
Las herramientas del módulo son más fáciles de reutilizar cuando cada transformación está separada. Consulta la guía de funciones en Python para organizar pipelines legibles.
Memoria y evaluación perezosa
La mayoría de los resultados no se calcula hasta que se solicita. Esto permite procesar entradas grandes sin guardarlas completas. Sin embargo, convertir con list() elimina esa ventaja. Si tu programa enfrenta límites de memoria, revisa cómo corregir MemoryError.
Programación funcional
itertools combina bien con generadores, map, filter y funciones pequeñas. El HOWTO oficial de programación funcional explica iteradores, generadores y patrones relacionados.
Errores frecuentes
Los problemas comunes son olvidar que un iterador se consume, dejar un iterador infinito sin límite, convertir millones de combinaciones en una lista, usar groupby sin ordenar y duplicar con tee iteradores que avanzan a velocidades muy diferentes.
Buenas prácticas
Empieza con la operación más simple que exprese la intención. Mantén los iteradores como iteradores hasta el último momento, limita resultados infinitos y mide antes de optimizar. itertools no reemplaza todos los bucles, pero ofrece componentes probados para construir iteraciones compactas, eficientes y fáciles de combinar.






