|
|
Функции фильтрации из модуля itertools
Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs
Следующая
функция filterfalse() модуля itertools работает по
аналогии с функцией filter(), которую мы рассматривали в базовом
курсе языка Python. Разница лишь в
том, что filterfalse() возвращает
элементы итерируемой последовательности, для которых функция условия возвращает
False. Например,
пусть имеется последовательность чисел:
Тогда, применяя
к ней функцию filterfalse(), получим:
res_it = filterfalse(lambda x: x % 2 == 0, digits)
res = list(res_it) # [1, 3]
Лямбда-функция
возвращает False для нечетных
значений, именно они и выделяются, как результат работы.
Или другой
пример. Допустим, что в следующем списке:
text = ["Hello", "", " ", None, "Python"]
нужно убрать все
пустые строки, включая пробельные символы и значения None. С помощью filterfalse() это можно
сделать следующим образом:
res_it = filterfalse(lambda x: True if x is None else not bool(x.strip()), text)
Как видите,
здесь мы имеем более сложное условие. Но принцип везде один: если для текущего
значения x функция условия
возвращает False, то элемент
остается, иначе отбрасывается.
Функция dropwhile()
Следующая
функция dropwhile() пропускает
элементы итерируемого объекта до тех пор, пока заданная предикатная функция (функция
условия) возвращает значение True, а затем возвращает все оставшиеся элементы.
Например, для
списка:
digits = [1, 2, -3, 4, 5, 6, -7, -8]
следующий вызов
функции dropwhile() вернет все
значения, начиная с первого отрицательного:
res_it = dropwhile(lambda x: x > 0, digits)
res = list(res_it) # [-3, 4, 5, 6, -7, -8]
Почему мы
получили такой результат? Очевидно, что для первых двух значений 1 и 2 списка digits лямбда-функция
возвращает True, следовательно,
они пропускаются. А для третьего значения -3 имеем False, поэтому все
элементы с 3-го и до последнего будут возвращаться итератором res_it.
Функцию dropwhile() удобно
использовать для упорядоченных, отсортированных последовательностей. В
частности, если значения отсортированы по возрастанию:
numbers = range(-10, 10, 2) # [-10, -8, -6, -4, -2, 0, 2, 4, 6, 8]
то dropwhile() позволяет
легко разбить ее на две части по заданному критерию. Например, пропустить
отрицательные и оставить положительные:
res_it = dropwhile(lambda x: x <= 0, numbers) # [2, 4, 6, 8]
Функция takewhile()
Противоположная
функция takewhile() наоборот
оставляет элементы итерируемого объекта, пока функция условия возвращает True. Например:
res_it = takewhile(lambda x: x <= 0, numbers) # [-10, -8, -6, -4, -2, 0]
res_it = takewhile(lambda x: x > 0, digits) # [1, 2]
Функция compress()
Последняя функция
compress(), которую мы
рассмотрим на этом занятии, позволяет отбирать элементы коллекции на основе
значений второй коллекции:
itertools.compress(data,
selectors)
- data –
обрабатываемая коллекция данных;
- selectors – коллекция,
определяющая, какие элементы оставить, а какие исключить.
Пусть, например,
у нас имеется список data с данными и
кортеж selector с селекторами:
data = ["яблоко", "груша", "банан", "виноград", "персик"]
selector = (True, False, True, False, True)
Тогда следующий
вызов функции compress():
res_it = compress(data, selector)
res = list(res_it) # ['яблоко', 'банан', 'персик']
оставит три
значения: 'яблоко', 'банан', 'персик', для которых элементы в selector равны True. Остальные
будут отброшены.
Этот же самый
пример можно записать и в другом виде. В качестве селекторов не обязательно
прописывать булевы значения True/False, можно
указывать любые другие данные, к которым допустимо применять функцию bool():
selector2 = (1, 0, 100, "", "hello", [])
Обратите
внимание, что длина кортежа selector2 на один больше списка data.
Давайте посмотрим, как отработает следующий вызов функции compress():
res_it = compress(data, selector2) # ['яблоко', 'банан', 'персик']
Увидим тот же
результат из трех элементов. То есть, длины передаваемых коллекций могут различаться
и тогда итерирование идет по самой короткой из них. В частности:
res_it = compress(data, selector2[:4]) # ['яблоко', 'банан']
Также в качестве
селектора можно объявить, например, выражение-генератор:
selector3 = (len(x) < 7 for x in data)
и указать его
вторым аргументом:
res_it = compress(data, selector3) # ['яблоко', 'груша', 'банан', 'персик']
На выходе
получим четыре строки, длины которых меньше семи.
Вот основные
функции фильтрации элементов коллекций модуля itertools.
Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs
|