Python, usando a función zip(): obtención dos elementos de varias listas á vez

Negocios

A función integrada de Python zip() combina os elementos de varios obxectos iterables (listas, tuplas, etc.) e úsase para recuperar os elementos de varias listas nun bucle for.

Esta sección describe o seguinte uso da función zip().

  • Obter os elementos de varias listas nun bucle for.
  • Tratar con diferentes números de elementos
    • zip():A función ignorará os elementos que son demasiado.
    • itertools.zip_longest():Esta función encherá os elementos que faltan.
  • Obter unha lista de tuplas de elementos de múltiples iterables.

Obter os elementos de varias listas nun bucle for.

Se queres recuperar e usar os elementos de varios obxectos iterables (listas, tuplas, etc.) ao mesmo tempo nun bucle for, especifícaos como argumentos para a 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

Non só dous, senón tamén tres ou máis.

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 diferentes números de elementos

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

Na función zip(), se o número de elementos de cada lista é diferente, devolverase ata o número de elementos menor (menor) e ignorarase o número maior.

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

A función itertools.zip_longest() encherá os elementos que faltan.

Usando zip_longest() no módulo itertools da biblioteca estándar, é posible encher os elementos que faltan con valores arbitrarios cando o número de elementos en cada lista é diferente.

Por defecto, énchese con Ningún.

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

Se se especifica o argumento fillvalue, cubrirase con ese valor.

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

Aínda que haxa varias listas con elementos que faltan, o valor a cubrir é uniforme. Non é 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

É posible especificar un valor diferente usando zip_longest() dentro de zip_longest(), pero non é práctico porque cómpre saber de antemán cales son os elementos da lista que faltan.

Se quere encher varias listas cun número descoñecido de elementos, cada un cun valor diferente, pódese considerar o seguinte procedemento.

  1. Defina valores para cubrir todas as listas.
  2. Obter o número máximo de elementos
  3. Encha todas as listas ata o máximo número de elementos
  4. Usando a 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

No proceso de encher ata o maior número de elementos, facemos o seguinte.

  • Inicialización dunha lista cun valor e número de elementos arbitrarios
  • + operador para unir listas

Se convertemos isto nunha función, parecerase así. A lista orixinal e os valores que enchen a lista especifícanse como argumentos iterables (lista ou 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

Usa a notación de comprensión de listas e a expansión da lista por *.

Obter unha lista de tuplas de elementos de múltiples iterables.

A función zip() devolve un iterador (obxecto zip) que é unha tupla de elementos de varios obxectos iterables.
Tamén se pode usar fóra do bucle for, e o destino non se limita ás listas.

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

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

Se quere obter unha lista dos elementos de varios obxectos iterables como unha tupla, use list() para facer unha 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'>