Инструменты итерации Python: filter (), islice (), map () и zip ()

Введение Python тронул сердца многих разработчиков программного обеспечения по всему миру благодаря своей полезности и простоте. Python предоставляет своим пользователям ряд полезных функций и структур данных, которые упрощают работу с данными, включая инструменты, используемые для эффективного циклического перебора данных, известные как itertools. Это руководство покажет вам, как использовать Python itertools для итерации по объектам с помощью: * filter () - функция filter () принимает заданную последовательность или итерацию вместе с

Вступление

Python тронул сердца многих разработчиков программного обеспечения по всему миру благодаря своей полезности и простоте.

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

Это руководство покажет вам, как использовать Python itertools для перебора объектов с помощью:

  • filter () - filter() принимает предоставленную последовательность или итерацию вместе с критерием фильтрации (функцией или лямбда). Затем он проверяет каждый элемент в последовательности, чтобы определить, соответствует ли элемент критериям фильтрации, возвращая только те элементы, которые соответствуют этим критериям.
  • islice () - islice() позволяет пользователю выполнять цикл итерации с start и stop и возвращает генератор.
  • map () - map() создает итерируемый объект карты, который применяет указанное преобразование к каждому элементу в выбранной итерации.
  • zip () - zip() принимает два итерационных объекта и возвращает кортеж из парных элементов. Первый элемент в обоих итерациях объединяется в пару, второй элемент в обоих итерациях объединяется в пары и так далее.

Мы начнем с определения итерационных объектов и итерационных функций, а затем перейдем к рассмотрению некоторых примеров четырех итерационных функций, упомянутых выше.

Примечание. Начиная с Python 3, filter() , map() и zip() функционально эквивалентны функциям itertools ifilter() , imap() и izip() . Все они возвращают итераторы и не требуют импорта.

islice() не был перенесен во встроенное пространство имен Python 3. Вам все равно придется импортировать itertools чтобы использовать его.

Что такое итерируемые объекты?

Итерируемый объект / итерация может быть определена как контейнер , содержащий данные , которые могут быть петельным / итерация. Итерируемые объекты в Python включают списки , наборы , кортежи и словари .

Обычно, когда мы работаем с повторяемыми объектами, мы перебираем их в цикле, используя базовые инструменты, такие как циклы for Мы часто игнорируем возможности и инструменты языка, которые могут помочь нам с итеративными задачами. Инструменты итерации предлагают эффективные, стандартизованные функции (аналогичные функциям, которые вы видите в языках функционального программирования, таких как Haskell), которые интегрируются с другими итерационными функциями, чтобы упростить итерационные задачи до нескольких строк кода.

Функция filter ()

filter() - это встроенная функция, которая позволяет нам брать группу итерируемых элементов и проверять, соответствуют ли элементы внутри итерации указанным вами критериям фильтрации:

 filter(function, iterable) 

Поскольку filter() возвращает генератор ( filter ), мы заключим его в list() чтобы преобразовать обратно в простой список. Если бы мы выполняли фильтрацию с помощью for и if , это выглядело бы примерно так:

 # Create a simple list numbered 0 to 10 
 number_list = [x for x in range(0,10)] 
 
 # Will filter for even numbers 
 even_numbers = [] 
 for number in number_list: 
 if number%2 == 0: 
 even_numbers.append(number) 
 
 print(even_numbers) 

Это приводит к:

 [0, 2, 4, 6, 8] 

Напротив, мы могли бы достичь того же результата, используя filter() и передавая в том же условии. Если условие удовлетворяется и True , оно не отфильтровывается. Если условие не выполняется и False , элемент итерации отфильтровывается.

Это условие может быть предоставлено либо как анонимная функция - lambda либо как отдельная функция:

 number_list = [x for x in range(0,10)] 
 
 filtered_list = list(filter(lambda number: number % 2 == 0, number_list)) 
 
 print(filtered_list) 

Когда предоставляется лямбда - number является элементом итерации, которую мы в данный момент фильтруем. Для каждого number мы проверяем, делится ли оно на 2. Если да - оно включается в новый вывод:

 [0, 2, 4, 6, 8] 

Пока функция возвращает True или False , вы можете выделить функцию как отдельную и просто сослаться на нее здесь вместо использования lambda :

 number_list = [x for x in range(0,10)] 
 
 def is_even(number): 
 return number%2==0 
 
 filtered_list = list(filter(is_even, number_list)) 
 print(filtered_list) 

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

 from itertools import filterfalse 
 number_list = [x for x in range(0,10)] 
 
 filtered_list = list(filterfalse(lambda number: number % 2 == 0, number_list)) 
 
 print(filtered_list) 

Это приводит к отфильтрованному списку нечетных чисел:

 [1, 3, 5, 7, 9] 

Вместо анонимной функции вы также можете использовать здесь автономную функцию:

 from itertools import filterfalse 
 number_list = [x for x in range(0,10)] 
 
 def is_even(number): 
 return number%2==0 
 
 filtered_list = list(filterfalse(is_even, number_list)) 
 
 print(filtered_list) 

Функция islice ()

Функция islice() является частью itertools , она принимает итерируемый объект и возвращает из него сегмент между элементами, определенными start и end аргументами, переданными функции:

 itertools.islice(iterable, start, end) 

Давайте islice() строку. Поскольку это возвращает генератор, мы заключим его в список, который также будет содержать результат. Если вы опустите start аргумент - функция будет нарезать до обязательного предоставленного end аргумента. Если оба предоставлены, он разделит их и вернет этот сегмент:

 from itertools import islice 
 old_string = "I need this, but not this" 
 print(list(islice(old_string, 11))) 

Здесь мы разрезали old_string от начала до 11-го элемента:

 ['I', ' ', 'n', 'e', 'e', 'd', ' ', 't', 'h', 'i', 's'] 

Однако, если мы предоставим start аргумент, мы можем вырезать определенный сегмент:

 from itertools import islice 
 old_string = "I need this, but not this" 
 
 print(list(islice(old_string, 7, 11))) 

 ['t', 'h', 'i', 's'] 

Обычно при работе с итерациями мы хотим получить итерацию, например список. Хотя нарезка также является обычной операцией для строк, и в этом случае нам обычно нужна строка, а не список. К счастью, легко join() элементы списка обратно в строку:

 print(''.join(list(islice(old_string, 0, 11)))) 

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

 I need this 

Функция map ()

Функция map принимает итерируемый объект и функцию, которая применяет преобразование ко всем элементам итерируемого:

 map(function, iterable) 

Функция map() включена во встроенные функции Python, поэтому нет необходимости ничего импортировать. map() предлагает те же функции, что и imap() из itertools в Python 2.

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

Скажем, вы хотите возвести каждый целочисленный элемент в степень 2:

 number_list = [x for x in range(0,10)] 
 
 numbers_powered = [] 
 for number in number_list: 
 numbers_powered.append(number**2) 
 print(numbers_powered) 

Это приводит к последовательности:

 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

Теперь мы можем упростить это с помощью map() :

 print(list(map(lambda x: x**2, number_list))) 

Для каждого элемента в number_list number_list - элемент возводится в степень двойки и помещается в новый список:

 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

Конечно, вместо анонимной функции вы также можете определить другие функции:

 number_list = [x for x in range(0,10)] 
 
 def function(number): 
 print("Performing transformation on number ", number) 
 return number**2 
 
 print('Original list: ', number_list) 
 
 mapped_list = list(map(function, number_list)) 
 
 print('Transformed list: ', mapped_list) 

Это приводит к:

 Original list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
 Performing transformation on number 0 
 Performing transformation on number 1 
 Performing transformation on number 2 
 Performing transformation on number 3 
 Performing transformation on number 4 
 Performing transformation on number 5 
 Performing transformation on number 6 
 Performing transformation on number 7 
 Performing transformation on number 8 
 Performing transformation on number 9 
 Transformed list: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

Функция zip ()

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

 zip(iterable_1, iterable_2, iterable_3...) 

Это встроенная функция, начиная с Python 3, и предлагает те же функции izip() что itertools предлагаемый в Python 2.

Давайте zip() вместе список имен и список идентификаторов, где первое имя заархивировано с первым идентификатором, второе имя - со вторым идентификатором, и так далее:

 names_list = ['Francis', 'Drake', 'Alexander', 'Robert', 'Elon'] 
 id_list = ['001', '002', '003', '004', '005'] 
 
 print(list(zip(names_list,id_list))) 

Это приводит к:

 [('Francis', '001'), ('Drake', '002'), ('Alexander', '003'), ('Robert', '004'), ('Elon', '005')] 

Примечание. Если эти итерации не имеют одинаковой формы, например, names_list с 5 элементами и id_list с 10 элементами, будут отображены только первые 5, а остальная часть id_list будет проигнорирована. Будет отображена самая длинная общая последовательность.

Как обычно, это возвращает генератор - поэтому мы заключили его в list() .

Такая же функциональность и поведение присутствует более чем в двух итерациях - фактически, вы можете предоставить неограниченное количество из них:

 names_list = ['Francis', 'Drake', 'Alexander', 'Robert', 'Elon'] 
 last_name_list = ['Brown', 'Johnson', 'Tiedemann', 'Mann'] 
 id_list = ['001', '002', '003', '004', '005'] 
 
 zipped_list = list(zip(names_list, last_name_list, id_list)) 
 print(zipped_list) 

 [('Francis', 'Brown', '001'), ('Drake', 'Johnson', '002'), ('Alexander', 'Tiedemann', '003'), ('Robert', 'Mann', '004')] 

Так как names_list имеет длину 5, а два других итератора имеют длину 4, последний элемент names_list не имеет пары.

Это отличный инструмент для группировки связанных элементов, которые появляются в разных контекстах.

Заключение

Python поставляется с рядом встроенных функций, которые помогают инженерам легко и эффективно манипулировать данными с помощью высокоуровневого API. Итерация - очень распространенная операция, и инструменты итерации Python очень удобны для однострочных операций с элементами в функциональном стиле.

В этом руководстве мы рассмотрели функции filter() , map() , islice() и zip() .

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

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus

Содержание