Zip python 3 пример

Функция zip. Примеры использования

На прошлых занятиях мы с вами познакомились с двумя функциями map() и filter(). На этом продолжим эту тему и поговорим о третьей часто применяемой функции:

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

Давайте в качестве простого примера возьмем два списка со значениями:

a = [1, 2, 3, 4] b = [5, 6, 7, 8, 9, 10]

и передадим их в качестве аргументов функции zip():

После запуска программы увидим, что переменная z ссылается на объект zip. Как вы уже догадались, это итератор, элементы которого перебираются функцией next():

Давайте переберем все пары через цикл for:

Здесь x является кортежем из соответствующих значений списков a и b. Причем последняя пара заканчивается числами (4, 8), когда функция zip() дошла до конца самого короткого списка.

Также всегда следует помнить, что функция zip() возвращает итератор. Это значит, что перебрать элементы можно только один раз. Например, повторный вызов оператора for для этой же функции:

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

Если нам все же нужно несколько раз обходить выделенные пары элементов, то их следует вначале преобразовать, например, в кортеж:

А, затем, обходить несчетное число раз. Но в этом случае увеличивается расход памяти, так как мы сохраняем все элементы в кортеже, а не генерируем «на лету» с помощью итератора. Так что, без особой необходимости делать преобразование к кортежу или списку не стоит.

В качестве перебираемых коллекций могут быть любые итерируемые объекты, например, строки. Если мы добавим строку:

и вызовем функцию zip() и с ней:

то в консоли увидим кортежи уже из трех значений, причем последнее будет соответствующим символом строки. Также, напомню, что оператор for можно записать с тремя переменными, если перебираемые значения являются кортежами:

for v1, v2, v3 in z: print(v1, v2, v3)

Иногда удобно кортеж сразу распаковать в отдельные переменные и использовать внутри цикла for.

Также все кортежи из функции zip() мы можем получить с помощью распаковки, используя запись:

z1, z2, z3, z4 = zip(a, b, c) print(z1, z2, z3, z4, sep="\n")

Здесь неявно вызывается функция next() для извлечения всех элементов. Или, можно записать так:

z1, *z2 = zip(a, b, c) print(z1, z2, sep="\n")

Тогда первое значение будет помещено в переменную z1, а все остальные – в список z2.

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

а, затем, распаковать его элементы с помощью оператора *:

то мы получим уже не список, а четыре кортежа, следующих друг за другом. Если передать их в таком виде на вход функции zip():

t1, t2, t3 = zip(*lz) print(t1, t2, t3, sep="\n")

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

t1, t2, t3 = zip((1, 5, 'p'), (2, 6, 'y'), (3, 7, 't'), (4, 8, 'h'))

Но те же самые кортежи мы можем получить гораздо проще, если распаковать непосредственно итератор z:

Как видите, к итератору вполне применим оператор распаковки элементов и на практике иногда этим пользуются.

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

Видео по теме

#1. Первое знакомство с Python Установка на компьютер

#2. Варианты исполнения команд. Переходим в PyCharm

#3. Переменные, оператор присваивания, функции type и id

#4. Числовые типы, арифметические операции

#5. Математические функции и работа с модулем math

#6. Функции print() и input(). Преобразование строк в числа int() и float()

#7. Логический тип bool. Операторы сравнения и операторы and, or, not

#8. Введение в строки. Базовые операции над строками

#9. Знакомство с индексами и срезами строк

#11. Спецсимволы, экранирование символов, row-строки

#12. Форматирование строк: метод format и F-строки

#13. Списки — операторы и функции работы с ними

#14. Срезы списков и сравнение списков

#15. Основные методы списков

#16. Вложенные списки, многомерные списки

#17. Условный оператор if. Конструкция if-else

#18. Вложенные условия и множественный выбор. Конструкция if-elif-else

#19. Тернарный условный оператор. Вложенное тернарное условие

#21. Операторы циклов break, continue и else

#22. Оператор цикла for. Функция range()

#23. Примеры работы оператора цикла for. Функция enumerate()

#24. Итератор и итерируемые объекты. Функции iter() и next()

#25. Вложенные циклы. Примеры задач с вложенными циклами

#26. Треугольник Паскаля как пример работы вложенных циклов

#27. Генераторы списков (List comprehensions)

#28. Вложенные генераторы списков

#29. Введение в словари (dict). Базовые операции над словарями

#30. Методы словаря, перебор элементов словаря в цикле

#31. Кортежи (tuple) и их методы

#32. Множества (set) и их методы

#33. Операции над множествами, сравнение множеств

#34. Генераторы множеств и генераторы словарей

#35. Функции: первое знакомство, определение def и их вызов

#36. Оператор return в функциях. Функциональное программирование

#37. Алгоритм Евклида для нахождения НОД

#38. Именованные аргументы. Фактические и формальные параметры

#39. Функции с произвольным числом параметров *args и **kwargs

#40. Операторы * и ** для упаковки и распаковки коллекций

#42. Анонимные (lambda) функции

#43. Области видимости переменных. Ключевые слова global и nonlocal

#45. Введение в декораторы функций

#46. Декораторы с параметрами. Сохранение свойств декорируемых функций

#47. Импорт стандартных модулей. Команды import и from

#48. Импорт собственных модулей

#49. Установка сторонних модулей (pip install). Пакетная установка

#50. Пакеты (package) в Python. Вложенные пакеты

#51. Функция open. Чтение данных из файла

#52. Исключение FileNotFoundError и менеджер контекста (with) для файлов

#53. Запись данных в файл в текстовом и бинарном режимах

#55. Функция-генератор. Оператор yield

#56. Функция map. Примеры ее использования

#57. Функция filter для отбора значений итерируемых объектов

#58. Функция zip. Примеры использования

#59. Сортировка с помощью метода sort и функции sorted

#60. Аргумент key для сортировки коллекций по ключу

#61. Функции isinstance и type для проверки типов данных

#62. Функции all и any. Примеры их использования

#63. Расширенное представление чисел. Системы счисления

#64. Битовые операции И, ИЛИ, НЕ, XOR. Сдвиговые операторы

#65. Модуль random стандартной библиотеки

#66. Аннотация базовыми типами

#67. Аннотации типов коллекций

#68. Аннотации типов на уровне классов

#69. Конструкция match/case. Первое знакомство

#70. Конструкция match/case с кортежами и списками

#71. Конструкция match/case со словарями и множествами

#72. Конструкция match/case. Примеры и особенности использования

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

Источник

Разбираемся, как работает встроенная функция zip в Python, и пишем свою реализацию с помощью list comprehension

Обложка: Разбираемся, как работает встроенная функция zip в Python, и пишем свою реализацию с помощью list comprehension

Многие слышали о функции zip в Python, а кто-то даже регулярно ей пользуется. Сегодня мы (из интереса и для общего развития) опишем, как можно реализовать её самому с помощью list comprehensions.

Для начала поясню, что вообще делает функция zip, для тех, кто с ней раньше не сталкивался:

>>> s = 'abc' >>> t = (10, 20, 30) >>> zip(s,t) [('a', 10), ('b', 20), ('c', 30)]

То есть функция берёт на вход несколько списков и создаёт из них список (в Python 3 создаётся не list, а специальный zip-объект) кортежей, такой, что первый элемент полученного списка содержит кортеж из первых элементов всех списков-аргументов. Таким образом, если ей передать три списка, то она отработает следующим образом:

>>> s = 'abc' >>> t = (10, 20, 30) >>> u = (-5, -10, -15) >>> list(zip(s,t,u)) [('a', 10, -5), ('b', 20, -10), ('c', 30, -15)]

В общем-то, функция отработает даже для одного iterable-объекта, результатом будет последовательность из кортежей, в каждом из которых будет по одному элементу. Но это, пожалуй, не самый распространенный способ применения zip. Я часто использую zip, например, для создания словарей:

>>> names = ['Tom', 'Dick', 'Harry'] >>> ages = [50, 35, 60] >>> dict(zip(names, ages))

Это весьма удобно, не находите? Каждый раз, когда я рассказываю о zip на своих уроках, у меня спрашивают о том, что будет, если в функцию передать массивы разной длины. Ответ простой — победит более короткий:

>>> s = 'abc' >>> t = (10, 20, 30, 40) >>> list(zip(s,t)) [('a', 10), ('b', 20), ('c', 30)] 

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

Есть одна возможность в Python, которая мне нравится даже больше, чем zip. Это списковое включение (англ. list comprehension). Именно поэтому, когда один из студентов недавно спросил меня, можем ли мы реализовать zip сами с помощью списковых включений, я просто не смог устоять.

Как же нам этого добиться? Начнём с первого, что приходит на ум:

[(s[i], t[i]) # создаём кортеж из двух элементов for i in range(len(s))] # для индексов от 0 до len(s) - 1

В общем-то всё! Это работает. Но есть несколько моментов, которые всё же стоит доработать в этом методе.

Во-первых, оригинальная функция могла работать с массивами разной длины. Поэтому вместо range(len(s)) нам стоит использовать range(len(x)) , где x — наиболее короткая последовательность. Для этого достаточно поместить все последовательности в один список, отсортировать этот список по длине элементов и выяснить длину элемента, оказавшегося под нулевым индексом:

>>> s = 'abcd' >>> t = (10, 20, 30) >>> sorted((s,t), key=len) [(10, 20, 30), 'abcd']

Совмещаем это с предыдущим кодом:

>>> s = 'abcd' >>> t = (10, 20, 30) >>> sorted((s,t), key=len) [(10, 20, 30), 'abcd']

Это ещё не все доработки, а выражение уже получается слишком длинным. Пожалуй, выяснение наименьшей длины стоит вынести в отдельную функцию (заодно сделаем так, чтобы она вычисляла наикратчайшую последовательность из неограниченного количества аргументов):

>>> def shortest_sequence_range(*args): return range(len(sorted(args, key=len)[0])) >>> [(s[i], t[i]) for i in shortest_sequence_range(s,t) ]

Что осталось теперь? Как уже говорилось выше, Python 3 создаёт не список, а специальный zip-объект, возвращая итератор от него. Это сделано для того, чтобы код не ломался при обработке исключительно длинных последовательностей. Это можно реализовать, но уже не с помощью спискового включения (которое всегда возвращает список), а с помощью генератора. К счастью, для этого достаточно поменять квадратные скобки на круглые:

>>> def shortest_sequence_range(*args): return range(len(sorted(args, key=len)[0])) >>> g = ((s[i], t[i]) for i in shortest_sequence_range(s,t) ) >>> for item in g: print(item) ('a', 10) ('b', 20) ('c', 30) 

Готово! Мы реализовали свой полностью рабочий zip. Вы можете потренироваться и самостоятельно подумать, как ещё можно улучшить этот алгоритм.

Источник

Читайте также:  Тестовая страница
Оцените статью