zip() combina elementos de múltiples iterables en pares (o tuplas) y devuelve un iterador. Es la forma idiomática de recorrer dos listas en paralelo, construir diccionarios desde listas separadas o transponer matrices.
zip básico: combinar dos o más listas
nombres = ["Ana", "Luis", "María"]
edades = [28, 34, 22]
ciudades = ["Madrid", "Barcelona", "Sevilla"]
# zip devuelve un iterador de tuplas
for nombre, edad in zip(nombres, edades):
print(f"{nombre}: {edad} años")
# Tres o más listas a la vez
for nombre, edad, ciudad in zip(nombres, edades, ciudades):
print(f"{nombre}, {edad}, {ciudad}")
# Convertir a lista
pares = list(zip(nombres, edades))
print(pares)
# [('Ana', 28), ('Luis', 34), ('María', 22)]
zip se detiene en el iterable más corto
a = [1, 2, 3, 4, 5] b = ["a", "b", "c"] print(list(zip(a, b))) # [(1, 'a'), (2, 'b'), (3, 'c')] se detiene en el elemento 3
Construir un diccionario con zip
claves = ["host", "puerto", "ssl", "timeout"]
valores = ["localhost", 5432, True, 30]
config = dict(zip(claves, valores))
print(config)
# {'host': 'localhost', 'puerto': 5432, 'ssl': True, 'timeout': 30}
# Invertir un diccionario
original = {"a": 1, "b": 2, "c": 3}
invertido = dict(zip(original.values(), original.keys()))
print(invertido) # {1: 'a', 2: 'b', 3: 'c'}
Transponer una matriz con *
matriz = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
transpuesta = list(zip(*matriz))
print(transpuesta)
# [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
# El operador * desempaqueta la lista de filas como argumentos a zip
# Es equivalente a: zip(matriz[0], matriz[1], matriz[2])
# Convertir cada fila a lista
transpuesta_listas = [list(fila) for fila in zip(*matriz)]
print(transpuesta_listas)
# [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
zip_longest: rellenar cuando las longitudes difieren
from itertools import zip_longest
semana1 = [1200, 980, 1050, 1300, 900]
semana2 = [1100, 1050, 980] # más corta
# zip se detiene en 3; zip_longest llega hasta 5
for d1, d2 in zip_longest(semana1, semana2, fillvalue=0):
diferencia = d1 - d2
signo = "+" if diferencia >= 0 else ""
print(f"S1:{d1} S2:{d2} Dif:{signo}{diferencia}")
Desempaquetar con * (unzip)
pares = [(1, "a"), (2, "b"), (3, "c")] # "Desempaquetar" una lista de tuplas en listas separadas numeros, letras = zip(*pares) print(list(numeros)) # [1, 2, 3] print(list(letras)) # ['a', 'b', 'c'] # Útil para separar coordenadas X e Y puntos = [(0, 0), (1, 3), (2, 1), (4, 5)] xs, ys = zip(*puntos) print(list(xs)) # [0, 1, 2, 4] print(list(ys)) # [0, 3, 1, 5]
zip() es la alternativa idiomática al acceso por índice cuando trabajas con múltiples listas relacionadas. Recuerda que devuelve un iterador (solo puede consumirse una vez) y que se detiene en el más corto; usa zip_longest cuando necesites recorrer hasta el final de todas las listas.
