Python, Uso de la función zip(): Obtención de los elementos de varias listas a la vez

Negocio

La función incorporada de Python zip() combina los elementos de múltiples objetos iterables (listas, tuplas, etc.) y se utiliza para recuperar los elementos de múltiples listas en un bucle for.

Esta sección describe el siguiente uso de la función zip().

  • Obtener los elementos de varias listas en un bucle for.
  • Tratar con un número diferente de elementos
    • zip():La función ignorará los elementos que sean demasiado.
    • itertools.zip_longest():Esta función rellena los elementos que faltan.
  • Obtener una lista de tuplas de elementos de múltiples iterables.

Obtener los elementos de varias listas en un bucle for.

Si desea recuperar y utilizar los elementos de varios objetos iterables (listas, tuplas, etc.) al mismo tiempo en un bucle for, especifíquelos como argumentos de la función zip().

names = ['Alice', 'Bob', 'Charlie']
ages = [24, 50, 18]

for name, age in zip(names, ages):
    print(name, age)
# Alice 24
# Bob 50
# Charlie 18

No sólo dos, sino también tres o más.

points = [100, 85, 90]

for name, age, point in zip(names, ages, points):
    print(name, age, point)
# Alice 24 100
# Bob 50 85
# Charlie 18 90

Tratar con un número diferente de elementos

La función zip() ignora un gran número de elementos.

En la función zip(), si el número de elementos de cada lista es diferente, se devolverá hasta el número menor (más corto) de elementos, y se ignorará el número mayor.

names = ['Alice', 'Bob', 'Charlie', 'Dave']
ages = [24, 50, 18]

for name, age in zip(names, ages):
    print(name, age)
# Alice 24
# Bob 50
# Charlie 18

La función itertools.zip_longest() rellenará los elementos que faltan.

Utilizando zip_longest() en el módulo itertools de la biblioteca estándar, es posible rellenar los elementos que faltan con valores arbitrarios cuando el número de elementos de cada lista es diferente.

Por defecto, se rellena con Ninguno.

from itertools import zip_longest

names = ['Alice', 'Bob', 'Charlie', 'Dave']
ages = [24, 50, 18]

for name, age in zip_longest(names, ages):
    print(name, age)
# Alice 24
# Bob 50
# Charlie 18
# Dave None

Si se especifica el argumento fillvalue, se rellenará con ese valor.

for name, age in zip_longest(names, ages, fillvalue=20):
    print(name, age)
# Alice 24
# Bob 50
# Charlie 18
# Dave 20

Aunque haya varias listas con elementos ausentes, el valor a rellenar es uniforme. No es posible especificar valores diferentes.

points = [100, 85]

for name, age, point in zip_longest(names, ages, points, fillvalue=20):
    print(name, age, point)
# Alice 24 100
# Bob 50 85
# Charlie 18 20
# Dave 20 20

Es posible especificar un valor diferente utilizando zip_longest() dentro de zip_longest(), pero no es práctico porque se necesita saber de antemano qué elementos de la lista faltan.

Si se desea llenar varias listas con un número desconocido de elementos, cada uno con un valor diferente, se puede considerar el siguiente procedimiento.

  1. Definir los valores a rellenar para todas las listas.
  2. Obtener el número máximo de elementos
  3. Llenar todas las listas hasta el número máximo de elementos
  4. Uso de la función zip()
fill_name = 'XXX'
fill_age = 20
fill_point = 50

len_names = len(names)
len_ages = len(ages)
len_points = len(points)

max_len = max(len_names, len_ages, len_points)

names = names + [fill_name] * (max_len - len_names)
ages = ages + [fill_age] * (max_len - len_ages)
points = points + [fill_point] * (max_len - len_points)

print(names)
print(ages)
print(points)
# ['Alice', 'Bob', 'Charlie', 'Dave']
# [24, 50, 18, 20]
# [100, 85, 50, 50]

for name, age, point in zip(names, ages, points):
    print(name, age, point)
# Alice 24 100
# Bob 50 85
# Charlie 18 50
# Dave 20 50

En el proceso de llenado hasta el mayor número de elementos, hacemos lo siguiente.

  • Inicializar una lista con un valor y un número de elementos arbitrarios
  • Operador + para unir listas

Si convertimos esto en una función, tiene el siguiente aspecto. La lista original y los valores que llenan la lista se especifican como argumentos iterables (lista o tupla), respectivamente.

def my_zip_longest(iterables, fillvalues):
    max_len = max(len(i) for i in iterables)
    return zip(*[list(i) + [v] * (max_len - len(i)) for i, v in zip(iterables, fillvalues)])

for name, age, point in my_zip_longest((names, ages, points), ('XXX', 20, 50)):
    print(name, age, point)
# Alice 24 100
# Bob 50 85
# Charlie 18 50
# Dave 20 50

Utiliza la notación de comprensión de listas y la expansión de listas por *.

Obtener una lista de tuplas de elementos de múltiples iterables.

La función zip() devuelve un iterador (objeto zip) que es una tupla de elementos de múltiples objetos iterables.
También puede utilizarse fuera del bucle for, y el objetivo no se limita a las listas.

names = ['Alice', 'Bob', 'Charlie']
ages = (24, 50, 18)

z = zip(names, ages)
print(z)
print(type(z))
# <zip object at 0x10b57b888>
# <class 'zip'>

Si quieres obtener una lista de los elementos de múltiples objetos iterables como una tupla, utiliza list() para hacer una lista.

l = list(zip(names, ages))
print(l)
print(type(l))
print(type(l[0]))
# [('Alice', 24), ('Bob', 50), ('Charlie', 18)]
# <class 'list'>
# <class 'tuple'>