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.
- Definir valores a preencher para todas as listas.
- Obter o número máximo de elementos
- Preencher todas as listas até ao número máximo de elementos
- 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 *.
- Artigos relacionados:Usando a notação Python list comprehensions
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'>