enumerate y zip en Python: diferencias y ejemplos

Dos secuencias de Python combinadas con enumerate y zip

enumerate y zip en Python resuelven dos recorridos frecuentes. enumerate añade un contador a un iterable; zip avanza por varios iterables en paralelo y agrupa sus elementos. Entender sus diferencias evita índices manuales, bucles difíciles de leer y desajustes silenciosos entre listas.

enumerate: obtener posición y valor

Un bucle directo entrega cada elemento, pero a veces también necesitas su posición:

nombres = ["Ana", "Luis", "Marta"]

for indice, nombre in enumerate(nombres):
    print(indice, nombre)

El resultado empieza en cero. Puedes cambiar el inicio sin sumar manualmente:

for posicion, nombre in enumerate(nombres, start=1):
    print(posicion, nombre)

El índice que produce enumerate es un contador del recorrido. En una lista coincide con su posición si empiezas en cero, pero no debes asumir que es una clave propia del dato.

Por qué evitar range(len(...))

Este patrón funciona, pero añade acceso por índice y ruido:

for i in range(len(nombres)):
    print(i, nombres[i])

enumerate expresa mejor la intención y funciona con cualquier iterable, no solo con objetos que admiten len e indexación. Usa range cuando necesitas generar números o controlar posiciones independientemente de los elementos.

zip: recorrer varias secuencias

zip combina el primer elemento de cada iterable, después el segundo y así sucesivamente:

productos = ["A", "B", "C"]
precios = [12.5, 8.0, 19.9]

for producto, precio in zip(productos, precios):
    print(producto, precio)

No crea una relación permanente entre las listas. Produce pares durante la iteración. Si necesitas un diccionario y las claves son únicas, puedes construirlo con dict(zip(productos, precios)).

El riesgo de longitudes diferentes

Por defecto, zip termina cuando se agota el iterable más corto. Si hay tres productos y solo dos precios, el último producto no aparece y no se genera automáticamente un error. Ese comportamiento puede ocultar datos faltantes.

En versiones modernas de Python, strict=True exige la misma longitud:

for producto, precio in zip(productos, precios, strict=True):
    print(producto, precio)

Si las longitudes difieren, se lanza ValueError. Úsalo cuando cada posición debe tener correspondencia. Si quieres conservar elementos sobrantes, itertools.zip_longest permite rellenar los ausentes con un valor explícito.

Combinar enumerate y zip

Puedes numerar pares de elementos sin gestionar índices:

for fila, (producto, precio) in enumerate(
    zip(productos, precios, strict=True), start=1
):
    print(fila, producto, precio)

Los paréntesis reflejan el desempaquetado: enumerate entrega contador y valor; ese valor es la tupla producida por zip.

Desempaquetar columnas

zip también puede transponer filas conceptualmente:

filas = [("A", 12.5), ("B", 8.0), ("C", 19.9)]
productos, precios = zip(*filas)

El asterisco pasa cada fila como argumento separado. El resultado son tuplas, no listas. Si filas está vacío, el desempaquetado falla porque no hay dos resultados; trata ese caso antes.

Iteradores y consumo único

En Python 3, zip y enumerate devuelven iteradores perezosos. No calculan todos los pares por adelantado y pueden trabajar con flujos grandes. Pero, una vez consumidos, quedan agotados:

pares = zip(productos, precios)
print(list(pares))
print(list(pares))  # lista vacía

Si necesitas recorrer el resultado varias veces, recrea el zip o materialízalo una vez. Para grandes volúmenes, evita list si puedes procesar cada elemento en streaming.

Ejemplo práctico: validar registros

Supón columnas separadas para correo y consentimiento. Usa zip con strict=True para garantizar alineación y enumerate para informar la fila:

for fila, (correo, acepta) in enumerate(
    zip(correos, consentimientos, strict=True), start=2
):
    if "@" not in correo:
        print(f"Fila {fila}: correo no válido")

start=2 puede representar la fila real si la primera contiene encabezados. La numeración mejora el diagnóstico sin alterar los datos.

Cuándo no usar zip

zip es correcto cuando la correspondencia depende de la posición. Si debes unir registros por identificador, utiliza un diccionario, una unión de pandas o una consulta de base de datos. Dos listas ordenadas de forma diferente pueden tener igual longitud y producir pares incorrectos sin error.

Tampoco uses enumerate para crear identificadores persistentes. Si filtras o reordenas la colección, el contador cambia. Guarda una clave del dominio cuando la identidad deba conservarse.

Legibilidad y tipos

Elige nombres que expresen el contenido y desempaqueta en el for. Evita variables genéricas como x o item cuando el bucle aplica lógica de negocio. Los analizadores de tipos pueden detectar algunas incompatibilidades, pero no prueban que dos secuencias estén semánticamente alineadas.

Regla de decisión

Usa enumerate para contador más elemento, zip para elementos paralelos y ambos cuando además necesitas número de fila. Activa strict cuando una diferencia de longitud sea un error. Si la relación se basa en una clave, deja de pensar en posiciones y realiza una unión explícita.

Estas funciones hacen el bucle más compacto, pero su mayor valor es declarar la intención: numerar, emparejar o validar correspondencias sin administrar índices a mano.

Continúa aprendiendo

Amplía este tema con comprensión de listas, diccionarios en Python, funciones lambda.

Fuentes oficiales y primarias

Preguntas frecuentes

¿Para qué sirve enumerate en Python?
Entrega un contador y cada elemento de un iterable durante el recorrido.

¿Para qué sirve zip?
Agrupa en paralelo elementos de varios iterables y produce tuplas durante la iteración.

¿Qué ocurre si las listas tienen distinta longitud?
zip normal termina con la más corta; con strict=True genera ValueError.

¿Puedo usar enumerate y zip juntos?
Sí. enumerate puede numerar cada tupla producida por zip mediante desempaquetado anidado.

¿zip devuelve una lista?
No en Python 3; devuelve un iterador perezoso que se consume al recorrerlo.

¿Debo unir tablas con zip?
Solo si la relación depende de la posición; para claves, usa una unión explícita.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir