Python, Brug af zip()-funktionen: Få elementerne i flere lister på én gang

Forretning

Pythons indbyggede funktion zip() kombinerer elementerne i flere iterable objekter (lister, tupler osv.) og bruges til at hente elementerne i flere lister i en for-loop.

I dette afsnit beskrives følgende brug af zip()-funktionen.

  • Hent elementerne i flere lister i en for-løkke.
  • Håndtering af forskellige antal elementer
    • zip():Funktionen vil ignorere de elementer, der er for meget.
    • itertools.zip_longest():Denne funktion vil udfylde de manglende elementer.
  • Hent en liste over tupler af elementer i flere iterables.

Hent elementerne i flere lister i en for-løkke.

Hvis du vil hente og bruge elementerne i flere iterable objekter (lister, tupler osv.) på samme tid i en for-loop, skal du angive dem som argumenter til zip()-funktionen.

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

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

Ikke bare to, men også tre eller flere.

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

Håndtering af forskellige antal elementer

Funktionen zip() ignorerer et stort antal elementer.

Hvis antallet af elementer i hver liste er forskelligt i zip()-funktionen, returneres op til det mindste (kortere) antal elementer, og det største antal ignoreres.

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

Funktionen itertools.zip_longest() vil udfylde de manglende elementer.

Ved hjælp af zip_longest() i standardbiblioteket itertools-modulet er det muligt at udfylde de manglende elementer med vilkårlige værdier, når antallet af elementer i hver liste er forskelligt.

Som standard er den udfyldt med 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

Hvis argumentet fillvalue er angivet, vil den blive udfyldt med denne værdi.

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

Selv hvis der er flere lister med manglende elementer, er den værdi, der skal udfyldes, ensartet. Det er ikke muligt at angive forskellige værdier.

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

Det er muligt at angive en anden værdi ved at bruge zip_longest() inde i zip_longest(), men det er ikke praktisk, fordi man på forhånd skal vide, hvilke elementer i listen der mangler.

Hvis du ønsker at udfylde flere lister med et ukendt antal elementer, hver med en anden værdi, kan du overveje følgende fremgangsmåde.

  1. Definer de værdier, der skal udfyldes for alle lister.
  2. Få det maksimale antal elementer
  3. Fyld alle lister op til det maksimale antal elementer
  4. Brug af zip()-funktionen
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

I processen med at fylde op til det største antal elementer gør vi følgende.

  • Initialisering af en liste med en vilkårlig værdi og et vilkårligt antal elementer
  • +-operatoren til at sammenføje lister

Hvis vi omdanner dette til en funktion, ser det således ud. Den oprindelige liste og de værdier, der fylder listen, angives som henholdsvis iterable-argumenter (liste eller tupel).

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

Den anvender list comprehension notation og listeudvidelse med *.

Hent en liste over tupler af elementer i flere iterables.

Funktionen zip() returnerer en iterator (zip-objekt), som er en tupel af elementer fra flere iterable-objekter.
Den kan også bruges uden for for-loop'en, og målet er ikke begrænset til lister.

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

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

Hvis du ønsker at få en liste over elementerne i flere iterable-objekter som en tupel, skal du bruge list() til at lave en liste.

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