Python, Использование функции zip(): Получение элементов нескольких списков одновременно

Бизнес

Встроенная в Python функция zip() объединяет элементы нескольких итерируемых объектов (списков, кортежей и т.д.) и используется для получения элементов нескольких списков в цикле for.

В этом разделе описывается следующее использование функции zip().

  • Получение элементов нескольких списков в цикле for.
  • Работа с различным количеством элементов
    • zip():Функция будет игнорировать элементы, которые слишком велики.
    • itertools.zip_longest():Эта функция заполнит недостающие элементы.
  • Получение списка кортежей элементов нескольких итерабельных таблиц.

Получение элементов нескольких списков в цикле for.

Если вы хотите получить и использовать элементы нескольких итерируемых объектов (списков, кортежей и т.д.) одновременно в цикле for, укажите их в качестве аргументов функции 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

Не только два, но и три и более.

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

Работа с различным количеством элементов

Функция zip() игнорирует большое количество элементов.

В функции zip(), если количество элементов в каждом списке разное, будет возвращено до меньшего (короткого) количества элементов, а большее количество будет проигнорировано.

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

Функция itertools.zip_longest() заполнит недостающие элементы.

Используя zip_longest() в модуле itertools стандартной библиотеки, можно заполнить недостающие элементы произвольными значениями, когда количество элементов в каждом списке различно.

По умолчанию он заполнен значением 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

Если указан аргумент fillvalue, он будет заполнен этим значением.

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

Даже если имеется несколько списков с отсутствующими элементами, заполняемое значение является единым. Невозможно указать разные значения.

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

Можно указать другое значение, используя zip_longest() внутри zip_longest(), но это непрактично, поскольку необходимо заранее знать, какие элементы списка отсутствуют.

Если вы хотите заполнить несколько списков неизвестным количеством элементов, каждый из которых имеет свое значение, можно рассмотреть следующую процедуру.

  1. Определите значения для заполнения всех списков.
  2. Получить максимальное количество элементов
  3. Заполните все списки до максимального количества элементов
  4. Использование функции 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

В процессе заполнения до наибольшего числа элементов мы делаем следующее.

  • Инициализация списка с произвольным значением и количеством элементов
  • Оператор + для объединения списков

Если мы превратим это в функцию, то она будет выглядеть следующим образом. В качестве аргументов iterables (список или кортеж) указывается исходный список и значения, заполняющие список, соответственно.

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

В нем используется нотация понимания списка и расширение списка с помощью *.

Получение списка кортежей элементов нескольких итерабельных таблиц.

Функция zip() возвращает итератор (объект zip), который представляет собой кортеж элементов нескольких итерируемых объектов.
Его также можно использовать вне цикла for, и цель не ограничивается списками.

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

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

Если вы хотите получить список элементов нескольких итерируемых объектов в виде кортежа, используйте 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'>
Copied title and URL