В Python с помощью функции filter() мы можем применить другую функцию к определенному итерируемомму объекту (такому, как список, строка, словарь, и так далее). Параллельно осуществляется проверка, необходимо ли сохранить определенный элемент, или же нет. Проще говоря, она фильтрует данные, и возвращает ту информацию, которая проходит этот фильтр.
Итерируемый объект выступает объектом фильтра. Элементы, для которых было возвращено булевое значение True функцией, сохраняются в нем. Затем с ним можно выполнять операции конвертации в list, tuple либо последовательности других типов с использованием фабричных методов. Сейчас разберемся в особенностях использования filter() вместе с последовательностями различных типов. А чтобы принципы работы были более понятными, рассмотрим некоторые примеры.
Синтаксис функции filter()
В эту функцию передается два параметра:
- Имя функции. Это переменная, которая называет функцию, которая создается.
- Итерируемый объект. В качестве него может выступать кортеж, множество, список, строка или любой другой созданный пользователем.
Синтаксис выглядит следующим образом.
# Синтаксис filter() filter(in_function|None, iterable) |__filter object
Функция осуществляет вызов заданной функции для каждого элемента объекта, как в цикле.
Теперь разберем описанный выше код. В качестве первого параметра мы использовали функцию, включающую условия для фильтрации входящих значений. Ею возвращается значение True либо False. Простыми словами, булевое. Если осуществить передачу None, то почти все элементы будут удалены. Останутся лишь те, которые по умолчанию будут возвращать True.
Итерируемый объект – это совокупность элементов (которая может быть как в стройной последовательности, так и нет), которая подвергается проверке на соответствие определенному условию либо перебираются поочердно/в случайном порядке. Немного громоздкое определение, но если выразить проще, итерируемым объектом является любая совокупность элементов, которые содержатся в одной переменной.
Каждый вызов функций для проверки использует один из объектов этой последовательности.
В качестве значения, которое возвращается функцией, используется объект filter, представляющий собой совокупность элементов, которые остались после проверки.
Примеры функции filter()
Фильтр нечетных чисел
В данном примере мы используем список числовых значений в качестве итерируемого примера.
# список чисел numbers = [1, 2, 4, 5, 7, 8, 10, 11]
А теперь давайте покажем, как работает функция, фильтрующая нечетные числа. Она передается вызову filter() в качестве первого аргумента.
# функция, которая фильтрует нечетные числа def filter_odd_num(in_num): if(in_num % 2) == 0: return True else: return False
А теперь давайте посмотрим на код, который получился в итоге.
""" Программа Python для фильтрации нечетных чисел в списке, используя функцию filter() """ # список чисел numbers = [1, 2, 4, 5, 7, 8, 10, 11] # функция, которая проверяет числа def filter_odd_num(in_num): if(in_num % 2) == 0: return True else: return False # Применение filter() для удаления нечетных чисел out_filter = filter(filter_odd_num, numbers) print("Тип объекта out_filter: ", type(out_filter)) print("Отфильтрованный список: ", list(out_filter))
Здесь обратите внимание на следующие аспекты:
- Функция filter() возвращает out_filter, а мы использовали typte() для проверки типа данных.
- Мы вызвали конструктор list() для конвертации объекта filter в список.
После того, как мы запустим получившийся код, результат получится следующим.
Тип объекта out_filter: <class ‘filter’> Отфильтрованный список: [2, 4, 8, 10]
Код фильтрует нечетные числа и отображает только четные в списке.
Фильтрация повторяющихся значений из двух списков
Функция используется для получения разницы между двумя числовыми последовательностями. Для этого надо фильтровать повторяющиеся элементы. Допустим, у нас есть два списка строк.
# Список строк с похожими элементами list1 = ["Python", "CSharp", "Java", "Go"] list2 = ["Python", "Scala", "JavaScript", "Go", "PHP", "CSharp"]
Обратите внимание, что некоторые элементы в них повторяются. А именно, языки программирования. Наша задача следующая: необходимо написать функцию, которая возвращает повторяющиеся значения.
# функция, которая проверяет строки на вхождение def filter_duplicate(string_to_check): if string_to_check in ll: return False else: return True
А теперь приведем фрагмент итогового кода.
""" Программа для поиска совпадений между двумя списками, используя функцию filter() """ # Список строк с похожими элементами list1 = ["Python", "CSharp", "Java", "Go"] list2 = ["Python", "Scala", "JavaScript", "Go", "PHP", "CSharp"] # функция, которая проверяет строки на вхождение def filter_duplicate(string_to_check): if string_to_check in ll: return False else: return True # Применение filter() для удаления повторяющихся строк ll = list2 out_filter = list(filter(filter_duplicate, list1)) ll = list1 out_filter += list(filter(filter_duplicate, list2)) print("Отфильтрованный список:", out_filter)
А теперь результат будет таким.
Отфильтрованный список: [‘Java’, ‘Scala’, ‘JavaScript’, ‘PHP’]
Таким образом, код возвращает разницу двух списков. Тем не менее, это только примеры того, как работает эта функция.
Как использовать лямбда-выражения с filter
Лямбда-функции очень популярны в Python. Это маленькие функции, которые можно записывать лаконично. Соответственно, и их синтаксис более лаконичный по сравнению с классическим «пайтоновским».
Они ведут себя аналогично встроенным функциям. Следовательно, ее можно указать в качестве аргумента при вызове функции-фильтра. Теперь не надо прописывать отдельную функцию для того, чтобы фильтровать данные. Давайте рассмотрим некоторые примеры того, как использовать лямбду, на практике.
Фильтрация стоп-слов из строкового значения
Предположим, нам из строки нужно убрать слова «в», «и», «по», «за». Для этого необходимо создать список, в котором они будут последовательно перечисляться.
list_of_stop_words = ["в", "и", "по", "за"]
А вот строка.
string_to_process = "Сервис по поиску работы и сотрудников HeadHunter опубликовал подборку высокооплачиваемых вакансий в России за август."
Как видим, в ней есть некоторые стоп-слова, которые нам необходимо удалить.
А теперь давайте рассмотрим код полностью.
""" Программа для удаления стоп-слов из строки используя функцию filter() """ # Список стоп-слов list_of_stop_words = ["в", "и", "по", "за"] # Строка со стоп-словами string_to_process = "Сервис по поиску работы и сотрудников HeadHunter опубликовал подборку высокооплачиваемых вакансий в России за август." # lambda-функция, фильтрующая стоп-слова split_str = string_to_process.split() filtered_str = ' '.join((filter(lambda s: s not in list_of_stop_words, split_str))) print("Отфильтрованная строка:a", filtered_str)
Так, как требуется удалить слово целиком, необходимо сначала разбить строку на слова. И только после этого отправить ее на фильтрацию. Оставшиеся же слова снова объединятся в единую строку.
Итоговый результат будет таким.
Отфильтрованная строка: Сервис поиску работы сотрудников HeadHunter опубликовал подборку высокооплачиваемых вакансий России август.
Пересечение двух массивов
А теперь давайте создадим лямбда-выражение, после чего используем функцию фильтрации для поиска элементов, которые в них совпадают.
Входные данные такие.
# Два массива, имеющие общие элементы arr1 = ['p','y','t','h','o','n',' ','3','.','0'] arr2 = ['p','y','d','e','v',' ','2','.','0']
Теперь создадим lambda-функцию, которая будет выполнять роль фильтра разницы и возвращать элементы, которые совпадают в двух итерируемых объектах.
# Лямбда с использованием filter() для поиска общих значений out = list(filter(lambda it: it in arr1, arr2))
А так будет выглядеть получившийся в итоге код.
""" Программа для поиска общих элементов в двух списках с использованием функции lambda и filter() """ # Два массива, имеющие общие элементы arr1 = ['p','y','t','h','o','n',' ','3','.','0'] arr2 = ['p','y','d','e','v',' ','2','.','0'] # Лямбда с использованием filter() для поиска общих значений def interSection(arr1, arr2): # find identical elements out = list(filter(lambda it: it in arr1, arr2)) return out # функция main if __name__ == "__main__": out = interSection(arr1, arr2) print("Отфильтрованный список:", out)
А после того, как запустить эти строки, результат получим следующий.
Отфильтрованный список: [‘p’, ‘y’, ‘ ‘, ‘.’, ‘0’]
Использование функции filter без функции
Да, в некоторых случаях можно не передавать функцию в качестве первого аргумента. В таком случае указывается None, который говорит о том, что значение отсутствует. После этого критерием для отбора будет служить равенство False. А те значения, которые являются истинными, остаются. Давайте возьмем такую последовательность в качестве примера.
# Список значений, которые могут быть True или False bools = ['bool', 0, None, True, False, 1-1, 2%2]
Далее код целиком для понимания того, как работает filter() с None в качестве аргумента.
""" Вызов функции filter() без функции """ # Список значений, которые могут быть True или False bools = ['bool', 0, None, True, False, 1, 1-1, 2%2] # Передали None вместо функции в filter() out = filter(None, bools) # Вывод результата for iter in out: print(iter)
А в результате исполнения этого кода будет выдано следующее.
bool True 1