Как использовать функцию 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] или в твиттере здесь, все комментарии и рекомендации приветствуются! Если вы хотите поговорить о каких-либо проектах или сотрудничать, это было бы здорово.