Python, Usando a função zip(): Obtendo os elementos de múltiplas listas ao mesmo tempo

O negócio

A função zip() integrada de Python combina os elementos de múltiplos objectos iteráveis (listas, tuplos, etc.) e é utilizada para recuperar os elementos de múltiplas listas num loop for for.

Esta secção descreve a seguinte utilização da função zip().

  • Obter os elementos de múltiplas listas num loop for for.
  • Lidar com diferentes números de elementos
    • zip():A função irá ignorar os elementos que são demasiados.
    • itertools.zip_longest():Esta função irá preencher os elementos em falta.
  • Obtenha uma lista de tuplos de elementos de iterables múltiplos.

Obter os elementos de múltiplas listas num loop for for.

Se quiser recuperar e utilizar os elementos de múltiplos objectos iteráveis (listas, tuplos, etc.) ao mesmo tempo num loop for for, especifique-os como argumentos para a função 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

Não apenas dois, mas também três ou mais.

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

Lidar com diferentes números de elementos

A função zip() ignora um grande número de elementos.

Na função zip(), se o número de elementos em cada lista for diferente, até ao menor (menor) número de elementos será devolvido, e o maior número será ignorado.

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 função itertools.zip_longest() irá preencher os elementos em falta.

Usando zip_longest() no módulo itertools da biblioteca padrão, é possível preencher os elementos em falta com valores arbitrários quando o número de elementos em cada lista é diferente.

Por defeito, é preenchido com Nenhum.

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 o argumento de fillvalue for especificado, será preenchido com esse valor.

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

Mesmo que existam múltiplas listas com elementos em falta, o valor a ser preenchido é uniforme. Não é possível 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

É possível especificar um valor diferente utilizando zip_longest() dentro de zip_longest(), mas não é prático porque é necessário saber antecipadamente quais os elementos da lista que faltam.

Se desejar preencher várias listas com um número desconhecido de elementos, cada uma com um valor diferente, pode ser considerado o seguinte procedimento.

  1. Definir valores a preencher para todas as listas.
  2. Obter o número máximo de elementos
  3. Preencher todas as listas até ao número máximo de elementos
  4. Usando a função 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 processo de enchimento até ao maior número de elementos, fazemos o seguinte.

  • Inicialização de uma lista com um valor arbitrário e número de elementos
  • + operador para juntar listas

Se transformarmos isto numa função, parece que é assim. A lista original e os valores que preenchem a lista são especificados como argumentos iterables (lista ou tuple), 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 notação de compreensão de lista e expansão de lista por *.

Obtenha uma lista de tuplos de elementos de iterables múltiplos.

A função zip() devolve um iterador (objecto zip) que é um tuple de elementos de múltiplos objectos iteráveis.
Também pode ser utilizado fora do loop, e o alvo não está limitado a 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 quiser obter uma lista dos elementos de múltiplos objectos iteráveis como um tuple, use lista() para fazer uma 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'>
Copied title and URL