Python, usare la funzione zip(): Ottenere gli elementi di più liste in una volta sola

Attività commerciale

La funzione built-in di Python zip() combina gli elementi di più oggetti iterabili (liste, tuple, ecc.) ed è usata per recuperare gli elementi di più liste in un ciclo for.

Questa sezione descrive il seguente uso della funzione zip().

  • Ottenere gli elementi di più liste in un ciclo for.
  • Trattare con un numero diverso di elementi
    • zip():La funzione ignorerà gli elementi che sono troppo.
    • itertools.zip_longest():Questa funzione riempirà gli elementi mancanti.
  • Ottiene una lista di tuple di elementi di più iterabili.

Ottenere gli elementi di più liste in un ciclo for.

Se volete recuperare e utilizzare gli elementi di più oggetti iterabili (liste, tuple, ecc.) allo stesso tempo in un ciclo for, specificateli come argomenti alla funzione 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 solo due, ma anche tre o più.

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

Trattare con un numero diverso di elementi

La funzione zip() ignora un gran numero di elementi.

Nella funzione zip(), se il numero di elementi in ogni lista è diverso, verrà restituito fino al numero minore (più corto) di elementi, e il numero maggiore verrà ignorato.

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 funzione itertools.zip_longest() riempirà gli elementi mancanti.

Usando zip_longest() nel modulo itertools della libreria standard, è possibile riempire gli elementi mancanti con valori arbitrari quando il numero di elementi in ogni lista è diverso.

Per impostazione predefinita, è riempito con None.

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 l'argomento fillvalue è specificato, sarà riempito con quel valore.

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

Anche se ci sono più liste con elementi mancanti, il valore da riempire è uniforme. Non è possibile specificare valori diversi.

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

È possibile specificare un valore diverso usando zip_longest() dentro zip_longest(), ma non è pratico perché bisogna sapere in anticipo quali elementi della lista mancano.

Se volete riempire più liste con un numero sconosciuto di elementi, ognuno con un valore diverso, si può considerare la seguente procedura.

  1. Definisci i valori da riempire per tutte le liste.
  2. Ottenere il numero massimo di elementi
  3. Riempire tutte le liste fino al numero massimo di elementi
  4. Usando la funzione 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

Nel processo di riempimento fino al maggior numero di elementi, facciamo quanto segue.

  • Inizializzare una lista con un valore e un numero di elementi arbitrari
  • operatore + per unire le liste

Se lo trasformiamo in una funzione, appare così. La lista originale e i valori che riempiono la lista sono specificati come argomenti iterabili (lista o tupla), rispettivamente.

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 la notazione di comprensione della lista e l'espansione della lista con *.

Ottiene una lista di tuple di elementi di più iterabili.

La funzione zip() restituisce un iteratore (oggetto zip) che è una tupla di elementi di più oggetti iterabili.
Può anche essere usato al di fuori del ciclo for, e l'obiettivo non è limitato alle liste.

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

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

Se volete ottenere una lista degli elementi di più oggetti iterabili come tupla, usate list() per fare 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'>