4 Функции фильтрации в Python из модуля Itertools, о которых вы, вероятно, не знали
4 фильтрационные функции в Python из модуля Itertools, о которых вы, возможно, не знали
В Python итераторы помогают вам писать более питонический код и работать более эффективно с длинными последовательностями. Встроенный модуль itertools предоставляет несколько полезных функций, которые создают итераторы.
Они особенно полезны, когда вы хотите просто пройти по итератору, извлечь элементы из последовательности и обработать их – все это без необходимости хранить их в памяти. Сегодня мы узнаем, как использовать следующие четыре функции фильтрации в itertools:
- filterfalse
- takewhile
- dropwhile
- islice
Давайте начнем!
- ChatGPT Enterprise – Отправляйтесь туда, куда ни один LLM не смел ступать раньше
- Кто заработает деньги на золотой лихорадке генеративного искусственного интеллекта?
- Интерпретируемый искусственный интеллект с помощью SHAP
Перед началом: Заметка о примерах кода
В этом учебнике:
- Все четыре функции, о которых мы будем говорить, возвращают итераторы. Для ясности мы будем работать с простыми последовательностями и использовать
list()
, чтобы получить список, содержащий все элементы, возвращаемые итератором. Но избегайте этого – если необходимо – при работе с длинными последовательностями. Потому что, когда вы это делаете, вы теряете экономию памяти, которую дает вам итератор. - Для простых предикатных функций вы также можете использовать лямбды. Но для лучшей читаемости мы определим обычные функции и будем использовать их в качестве предикатов.
1. filterfalse
Если вы программировали на Python некоторое время, вы, вероятно, использовали встроенную функцию filter
с синтаксисом:
filter(pred,seq)
# pred: предикатная функция
# seq: любой допустимый итерируемый объект Python
Функция filter
возвращает итератор, который возвращает элементы из последовательности, для которых предикат возвращает True
.
Давайте рассмотрим пример:
nums = list(range(1,11)) #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def is_even(n):
return n % 2 == 0
Здесь список nums
и функция is_even
являются последовательностью и предикатом соответственно.
Чтобы получить список всех четных чисел в nums
, мы используем filter
следующим образом:
nums_even = filter(is_even, nums)
print(list(nums_even))
Output >>> [2, 4, 6, 8, 10]
Теперь давайте узнаем о filterfalse
. Мы импортируем функцию filterfalse
(и все остальные функции, о которых мы будем говорить) из модуля itertools.
Как следует из названия, filterfalse
делает противоположное тому, что делает функция filter
. Она возвращает итератор, который возвращает элементы, для которых предикат возвращает False
. Вот синтаксис для использования функции filterfalse
:
from itertools import filterfalse
filterfalse(pred,seq)
Функция is_even
возвращает False
для всех нечетных чисел в nums
. Таким образом, список nums_odd
, полученный с помощью filterfalse
, является списком всех нечетных чисел в nums
:
from itertools import filterfalse
nums_odd = filterfalse(is_even, nums)
print(list(nums_odd))
Output >>> [1, 3, 5, 7, 9]
2. takewhile
Синтаксис использования функции takewhile
таков:
from itertools import takewhile
takewhile(pred,seq)
Функция takewhile
возвращает итератор, который возвращает элементы до тех пор, пока предикатная функция возвращает True
. Она перестает возвращать элементы, когда предикат возвращает False
в первый раз.
Для последовательности длины n, если seq[k]
– первый элемент, для которого предикатная функция возвращает False
, то итератор возвращает seq[0]
, seq[1]
,…, seq[k-1]
.
Рассмотрим следующий список nums
и предикатную функцию is_less_than_5
. Мы используем функцию takewhile
следующим образом:
from itertools import takewhile
def is_less_than_5(n):
return n < 5
nums = [1, 3, 5, 2, 4, 6]
filtered_nums_1 = takewhile(is_less_than_5, nums)
print(list(filtered_nums_1))
Здесь предикат is_less_than_5
возвращает False
– в первый раз – для числа 5:
Вывод >>> [1, 3]
3. dropwhile
Функционально, функция dropwhile
делает обратное тому, что делает функция takewhile
.
Вот как вы можете использовать функцию dropwhile
:
from itertools import dropwhile
dropwhile(pred,seq)
Функция dropwhile
возвращает итератор, который пропускает элементы, пока предикат возвращает True
. Это означает, что итератор не возвращает ничего, пока предикат в первый раз не вернет False
. И как только предикат вернет False
, итератор возвращает все последующие элементы последовательности.
Для последовательности длины n, если seq[k]
– первый элемент, для которого предикатная функция возвращает False
, то итератор возвращает seq[k]
, seq[k+1]
,…, seq[n-1]
.
Давайте использовать ту же последовательность и предикат:
from itertools import dropwhile
def is_less_than_5(n):
return n < 5
nums = [1, 3, 5, 2, 4, 6]
filtered_nums_2 = dropwhile(is_less_than_5, nums)
print(list(filtered_nums_2))
Поскольку предикатная функция is_less_than_5
возвращает False
– в первый раз – для элемента 5, мы получаем все элементы последовательности, начиная с 5:
Вывод >>> [5, 2, 4, 6]
4. islice
Вы уже знакомы с срезанием итерируемых объектов в Python, таких как списки, кортежи и строки. Синтаксис среза выглядит так: iterable[start:stop:step]
.
Однако у этого подхода с срезанием есть следующие недостатки:
- При работе с большими последовательностями каждый срез или подпоследовательность – это копия, которая занимает память. Это может быть неэффективно.
- Поскольку шаг также может принимать отрицательные значения, использование значений начала, конца и шага влияет на читаемость кода.
Функция islice
решает указанные выше ограничения:
- Она возвращает итератор.
- Она не позволяет использовать отрицательные значения для шага.
Вы можете использовать функцию islice
следующим образом:
from itertools import islice
islice(seq,start,stop,step)
Вот несколько различных способов использования функции islice
:
- Использование
islice(seq, stop)
возвращает итератор для срезаseq[0]
,seq[1]
,…,seq[stop - 1]
. - Если вы указываете значения начала и конца:
islice(seq, start, stop)
, функция возвращает итератор для срезаseq[start]
,seq[start + 1]
,…,seq[start + stop - 1]
. - Когда вы указываете аргументы начала, конца и шага, функция возвращает итератор для среза
seq[start]
,seq[start + step]
,seq[start + 2*step]
,…,seq[start + k*step]
. При этом должно выполняться условиеstart + k*step
<stop
, аstart + (k+1)*step
>=stop
.
Давайте рассмотрим пример списка, чтобы лучше понять:
nums = list(range(10)) #[0,1, 2, 3, 4, 5, 6, 7, 8, 9]
Теперь давайте воспользуемся функцией islice
с помощью изученного синтаксиса.
Использование только значения конца
Давайте укажем только индекс конца:
from itertools import islice
# только конец
sliced_nums = islice(nums, 5)
print(list(sliced_nums))
И вот результат:
Output >>> [0, 1, 2, 3, 4]
Использование начального и конечного значений
Здесь мы используем и начальное, и конечное значения:
# начало и конец
sliced_nums = islice(nums, 2, 7)
print(list(sliced_nums))
Срез начинается с индекса 2 и распространяется до индекса 7 (не включая его):
Output >>> [2, 3, 4, 5, 6]
Использование начального, конечного и шагового значений
Когда мы используем начальное, конечное и шаговое значения:
# с использованием начала, конца и шага
sliced_nums = islice(nums, 2, 8, 2)
print(list(sliced_nums))
Мы получаем срез, начинающийся с индекса 2, распространяющийся до индекса 8 (не включая его), с шагом 2 (возвращая каждый второй элемент).
Output >>> [2, 4, 6]
Завершение
Я надеюсь, что этот учебник помог вам понять основы функций фильтрации itertools. Вы увидели несколько простых примеров, чтобы лучше понять работу этих функций. Далее вы можете изучить, как работают генераторы, генераторные функции и выражения, как эффективные итераторы python. Bala Priya C – разработчик и технический писатель из Индии. Ей нравится работать на пересечении математики, программирования, науки о данных и создания контента. Ее интересы и экспертиза включают DevOps, науку о данных и обработку естественного языка. Она любит читать, писать, кодировать и кофе! В настоящее время она работает над изучением и делится своими знаниями с сообществом разработчиков, создавая учебники, руководства, мнения и многое другое.