Python, Użycie funkcji zip(): Pobieranie elementów z wielu list naraz

Biznes

Wbudowana funkcja Pythona zip() łączy elementy wielu obiektów iterowalnych (list, tupli, itp.) i jest używana do pobierania elementów wielu list w pętli for.

Ta sekcja opisuje następujący sposób użycia funkcji zip().

  • Pobierz elementy z wielu list w pętli for.
  • Radzenie sobie z różną liczbą elementów
    • zip():Funkcja będzie ignorować elementy, które są zbyt duże.
    • itertools.zip_longest():Funkcja ta uzupełni brakujące elementy.
  • Uzyskaj listę krotek elementów wielu iterables.

Pobierz elementy z wielu list w pętli for.

Jeśli chcesz pobrać i użyć elementów wielu obiektów iterowalnych (list, tupli, itd.) w tym samym czasie w pętli for, podaj je jako argumenty funkcji 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

Nie tylko dwa, ale również trzy lub więcej.

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

Radzenie sobie z różną liczbą elementów

Funkcja zip() ignoruje dużą liczbę elementów.

W funkcji zip(), jeśli liczba elementów w każdej z list jest różna, zwrócona zostanie mniejsza (krótsza) liczba elementów, a większa zostanie zignorowana.

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

Funkcja itertools.zip_longest() uzupełni brakujące elementy.

Korzystając z funkcji zip_longest() w module itertools biblioteki standardowej, można uzupełnić brakujące elementy dowolnymi wartościami, gdy liczba elementów na każdej liście jest różna.

Domyślnie wypełniony jest wartością 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

Jeśli podano argument fillvalue, zostanie on wypełniony tą wartością.

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

Nawet jeśli istnieje wiele list z brakującymi elementami, wartość do wypełnienia jest jednolita. Nie jest możliwe określenie różnych wartości.

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

Możliwe jest określenie innej wartości poprzez użycie zip_longest() wewnątrz zip_longest(), ale nie jest to praktyczne, ponieważ musisz wiedzieć z góry, których elementów listy brakuje.

Jeśli chcesz wypełnić wiele list nieznaną liczbą elementów, z których każdy ma inną wartość, możesz rozważyć następującą procedurę.

  1. Określa wartości do wypełnienia dla wszystkich list.
  2. Uzyskaj maksymalną liczbę elementów
  3. Wypełnij wszystkie listy do maksymalnej liczby elementów
  4. Użycie funkcji 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

W procesie uzupełniania do największej liczby elementów wykonujemy następujące czynności.

  • Inicjalizacja listy z dowolną wartością i liczbą elementów
  • Operator + do łączenia list

Jeśli przekształcimy to w funkcję, wygląda to tak. Oryginalna lista i wartości, które wypełniają listę są określone jako argumenty iterables (lista lub tuple), odpowiednio.

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

Używa notacji list comprehension i rozwijania list przez *.

Uzyskaj listę krotek elementów wielu iterables.

Funkcja zip() zwraca iterator (obiekt zip), który jest tuple'em elementów wielu obiektów iterowalnych.
Może być również używany poza pętlą for, a cel nie jest ograniczony do list.

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

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

Jeśli chcesz uzyskać listę elementów wielu obiektów iterowalnych jako tuple, użyj list() aby utworzyć listę.

l = list(zip(names, ages))
print(l)
print(type(l))
print(type(l[0]))
# [('Alice', 24), ('Bob', 50), ('Charlie', 18)]
# <class 'list'>
# <class 'tuple'>