Как использовать функцию Zip в Python, часть 2

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

Функция zip без аргументов

Функция zip без аргументов создаст пустой итератор.

zip()

Вывод:

<zip at 0x18b85ba4f88>

Функция zip без аргументов, когда мы применяем функцию списка, она вернет пустой список

list(zip())

Вывод:

[]

Это самая простая функция zip, о которой мы можем говорить, но на самом деле мало что показывает, что вы можете делать с этой функцией.

Функция zip с одним аргументом

Zip-архивирование с одной итерацией показывает нам, как работает zip-функция, поскольку zip-функция не имеет возможности комбинировать другую итерацию. Итак, как питон это интерпретирует?

zip(name)
list(zip(name))

Выход:

[('A',), ('a',), ('r',), ('o',), ('n',)]

Мы, вероятно, могли догадаться, что Python будет интерпретировать таким образом, второй индекс кортежа пуст.

Что важно, функция zip может принимать бесконечное количество аргументов и поэтому полезна, когда мы хотим объединить данные.

Функция zip с более чем двумя аргументами

Итак, вначале мы рассмотрели функцию zip с двумя аргументами, чтобы дать вам представление о том, что такое zip-функция. А как насчет других аргументов? Как питон с этим справится?

name = 'Aaron'
name2 = 'Marky'
name3 = 'Smith'
list(zip(name1,name2,name3))

Вывод:

[('A', 'M', 'S'), 
('a', 'a', 'm'), 
('r', 'r', 'i'),
('o', 'k', 't'),
('n', 'y', 'h')]

Посмотрите, как каждый первый индекс строки объединяется в кортеж? Это можно использовать для объединения данных для бесконечного количества структур данных.

Функция zip с итерациями неравной длины

Теперь, когда мы познакомились с основами использования функции zip, что делать, если итерации неравномерны? Теперь это требует немного большего объяснения, и необходимо использовать пакет itertools.

Здесь мы импортируем zip_longest из пакета itertools. Затем мы хотим объединить три списка разной длины.

from itertools import zip_longest

a = [1,2,3,4,5]
b = ['a','b','c','d']
c = ['x','y','z']
print list(izip_longest(a,b,c))

Вывод:

[(1, 'a', 'x'), (2, 'b', 'y'), (3, 'c', 'z'), (4, 'd', None), (5, None, None)]

Обратите внимание, что ни один элемент в кортежах не представляет отсутствующие данные из конкретных объединяемых списков.

Вы также можете указать другой fillvalue, по умолчанию None:

print list(izip_longest(a, b, c,fillvalue=0))
[(1, 'a', 'x'), (2, 'b', 'y'), (3, 'c', 'z'), (4, 'd', 0), (5, 0, 0)]

Распаковка функции zip

Помните эту * часть синтаксиса функции zip в первой статье? Это называется оператором звездочки.

name = 'Aaron'
name2 = 'Smith'
pairs = list(zip(name,name2))

Теперь мы знаем результат этого:

[('A', 'S'), ('a', 'm'), ('r', 'i'), ('o', 't'), ('n', 'h')]

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

first, last = zip(*pairs)
print(first)
print(last)

Вывод:

('A','a','r','o','n')
('S','m','i','t','h')

Я лишь вкратце рассказал о возможностях оператора звездочки. Если вы хотите узнать больше, смотрите здесь.

Итак, теперь мы видим, что объединение данных в zip-функцию может быть полезно, когда мы хотим иметь доступ к двум или более переменным одновременно, особенно когда мы хотим выполнить цикл для нескольких итераций. Или если мы хотим записать данные в CSV?

Здесь мы применим это на практике.

Пример 1

Первое место, где я использовал эту функцию, было в сценарии, который я создавал для загрузки PDF-файлов с веб-сайта.

Теперь сценарий был написан для захвата нескольких PDF-файлов, и мне нужно было перебрать несколько PDF-ссылок и одновременно получить доступ к соответствующему имени файла. Ссылки pdf были в списках, а соответствующие имена файлов были в другом списке. Это была прекрасная возможность использовать функцию zip! Это позволило бы мне одновременно получить доступ как к ссылке в формате pdf, так и к соответствующему имени файла. Затем мы могли бы пройти через эту zip-функцию, чтобы получить каждую ссылку pdf и соответствующее имя файла для загрузки pdf.

Вот фрагмент кода, который необходим для получения PDF-файла.

import requests
folder = 'c:/Users/Aaron/'
def grab_pdf(pdf_links,names):
    for pdf, name in zip(pdf_links,names):
        myfile = requests.get(pdf, allow_redirects=True)
        file_name = folder + name + '.pdf'
    
        with open(file_name,'wb') as Pypdf:
            Pypdf.write(myfile.content)

Давайте рассмотрим этот код построчно.

import requests
folder = 'c:/Users/Aaron/'

Здесь мы импортировали пакет запросов (если вы не знакомы с пакетом запросов, см. Здесь), а также определили имя папки.

def grab_pdf(pdf_links,names):

Здесь мы определили функцию grab_pdf, списки pdf_links и имена которой загружаются в функцию.

for pdf, name in zip(pdf_links,names):

Мы запускаем цикл for здесь через функцию zip, мы назначаем переменные pdf и name функции zip. Сделав это, мы теперь можем получить доступ к каждому объекту внутри кортежа с помощью переменных pdf и name.

Если бы мы должны были напечатать pdf и имя в первой итерации цикла, мы бы разделили первый кортеж, создаваемый функцией zip. Это ключ к функции zip, мы можем получить доступ как к отдельной ссылке pdf, так и к имени этого pdf-файла одновременно и что-то сделать с обеими этими переменными.

myfile = requests.get(pdf, allow_redirects=True)
        file_name = folder + name + '.pdf'

Затем мы назначаем переменную myfile и берем отдельный PDF-файл. Обратите внимание, что часть allow_redirects = True означает, что если предоставленная ссылка перенаправляет на другой URL-адрес, запрос будет следовать по этой ссылке. Мы также создали переменную file_name для доступа к соответствующему заголовку pdf.

with open(file_name,'wb') as Pypdf:
            Pypdf.write(myfile.content)

Здесь мы используем оператор with, это упрощает работу с функцией open, поскольку нам не нужно определять, когда закрывать функцию open. Пожалуйста, см. Здесь для получения дополнительной информации о заявлении with.

Функция open используется с нашим вновь созданным именем файла, и мы записываем двоичные данные, захваченные модулем запросов, в это имя файла. Обратите внимание, что myfile.content необходим для захвата двоичных данных. Если вы не знакомы с функцией открытия, см. Раздел Работа с файлами в W3School.

Также, если вы не знакомы с захватом PDF-файлов с помощью Python, прочтите полезную статью здесь.

Это вторая статья из трех, пожалуйста, прочтите третью статью, в которой будут приведены еще несколько примеров того, как функцию zip можно использовать на практике!

Об авторе

Я врач, который очень интересуется преподаванием, питоном, технологиями и здравоохранением. Я живу в Великобритании, преподаю онлайн-клиническое образование, а также веду веб-сайты www.coding-medics.com.

Вы можете связаться со мной по адресу [email protected] или в твиттере здесь, все комментарии и рекомендации приветствуются! Если вы хотите поговорить о каких-либо проектах или сотрудничать, это было бы здорово.

Статьи по Теме