zip() en Python: combinar iterables, desempaquetar con * y zip_longest

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.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP