№31 Функция Filter() / для начинающих

Предыдущий урок: Генераторы

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

Объект фильтра — это итерируемый объект. Он сохраняет те элементы, для которых функция вернула 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, а для проверки типа данных использовалась type();
  • Конструктор list() был вызван для конвертации объекта filter в список Python.

После запуска примера выйдет следующий результат:

Тип объекта 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 также работает как встроенная функция. Таким образом ее можно указать вместо функции в качестве аргумента при вызове filter() и избавиться от необходимости написания отдельной функции для фильтрации.

Рассмотрим некоторые примеры того, как использовать лямбда.

Отфильтровать стоп-слова из строки

В этом примере удалим стоп-слова из строки. Они перечислены в следующем списке.


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 без функции

Да, можно вызывать функцию 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

Теперь вы должны лучше понимать принцип работы функции filter() в Python.

Далее: Функция round()