Как работает функция filter() в Python

Python вот уже который год занимает первые места среди самых популярных языков программирования. По рейтингу от TIOBE Software в 2021 году Python занял первое место по популярности. Конечно, столь популярный язык используется и при работе во всех современных облачных сервисах, в том числе и в cloud.timeweb.com. В сегодняшней статье мы расскажем о применении функции Python – filter(), являющейся одной из самых важных в этом языке программирования.

Как Работает Функция Filter() В Python (1)

Filter() – это функция встроенная в стандартный Python, т.е. не требует импорта библиотек.

Синтаксис

На вход подается 2 параметра – функция и итерируемый объект.

filter(function, iterable)

function – функция с одним аргументом. Именно по ней фильтруются значения.

Итерируемый объект “iterable” может содержать любую итерацию – список, кортеж, словарь и т.д. Также может содержать объекты генератора или итератора. Filter() принимает только один итерируемый объект.

Механизм работы следующий: функция filter() разбивает переданный итерируемый объект на элементы и передает каждый их них в функцию (function), которая возвращает значение (True, False или что-то другое: число, строка и т.д.). Filter оценивает полученное значение и, если оно True (не именно равно ‘True’, а вообще истинно), добавляет его в итератор, если нет, то нет. Результатом работы является объект — итератор, содержащий только элементы, которые при фильтрации получили значение True.

Чтобы получить значения, которые были оценены как False, используется функция:

itertools.filterfalse()

Функция filter Python более эффективна по времени выполнения, чем цикл for, через который тоже можно сделать фильтрацию. Другим преимуществом является то, что функция filter возвращает итератор, что является более эффективным использованием памяти. Это было введено для filter в python 3. В версии python 2 функция фильтр возвращает объект типа list.

Разобрав основы функции, давайте посмотрим, как работает filter() на различных примерах.

Применение filter() с пользовательской функцией

Одним из самых простых примеров является фильтр четных чисел.

numbers = [1, 2, 3, 4, 5, 7, 10, 11]
def filter_num(num):
if(num % 2) != 0:
return True
else:
return False
out_filter = filter(filter_num, numbers)
print("Отфильтрованный список: ", list(out_filter))

В данном случае мы передаем в filter() пользовательскую функцию (filter_num) и список чисел - numbers.

Результатом работы будет:

Отфильтрованный список: [1, 3, 5, 7, 11]

Наша пользовательская функция проверяет каждый элемент списка на нечетность. Для этого, как мы знаем, должен быть ненулевой остаток при делении на 2. В случае если число нечетное, функция возвращает True, а значит этот элемент попадает в итоговый итератор.

Так как функция filter() возвращает объект с типом - <class 'filter'>, для получения самого результата необходимо преобразовать вывод. Например, мы преобразовали его в объект типа list (список). Этот пример возможно также реализовать с использованием лямбда-функции:

filter(lambda n: n % 2 != 0, numbers)

Следующий пример работы позволяет найти пересечение двух массивов.

Входные данные:

arr1 = ['1', '2', '3', '4', 5, 6, 7]
arr2 = [1, '2', 3, '4', '5', '6', 7]

Пишем функцию для поиска пересечений:

def intersection(arr1, arr2):
out = list(filter(lambda it: it in arr1, arr2))
return out

Она принимает на вход 2 массива, которые нужно проверить. После этого с помощью лямбда-функции находятся общие элементы.

Вызов функции и вывод результата:

out = intersection(arr1, arr2)
print("Отфильтрованный список:", out)

Результат работы:

Отфильтрованный список: ['2', '4', 7]

Применение filter() с лямбда-функцией

Функция filter также может принимать на вход лямбда-функции. Например, создадим детектор палиндромов:

Код:

word = ["cat", "rewire", "level", "book", "stats", "list"]
palindromes = list(filter(lambda word: word == word[::-1], word))
print("Слова палиндромы: ", list(palindromes))

Результат выполнения:

Слова палиндромы: ['level', 'stats']

Лямбда-функция проверяет, равно ли слово самому себе, написанному наоборот. Если это так, то возвращает True.

Применение filter() с фильтрацией выбросов в выборке

Импортируем библиотеку для статистических вычислений и задаем нормально распределенную выборку с несколькими выбросами.

import statistics as st
sample = [10, 8, 10, 8, 2, 7, 9, 3, 34, 9, 5, 9, 25]

Найдем среднее значение:

mean = st.mean(sample)
mean: 10.69

В выборках с нормальным распределением зачастую выбросы определяются как значения, которые отличаются от среднего более чем на 2 стандартных отклонения.

stdev = st.stdev(sample)
low = mean - 2*stdev
high = mean + 2*stdev

Находим стандартное отклонение, верхнюю и нижнюю границы. Затем фильтруем нашу выборку:

clean_sample = list(filter(lambda x: low <= x <= high, sample))

Результат работы:

[10, 8, 10, 8, 2, 7, 9, 3, 9, 5, 9, 25]

Очевидно, что значение 34 было выбросом. Теперь наше среднее значение равно: 8.75

Если провести еще одну итерацию данного метода, то значение 25 будет также отфильтровано.

Выборка без выбросов: [10, 8, 10, 8, 2, 7, 9, 3, 9, 5, 9]

Среднее значение 7.273 имеет значительную разницу с первоначальным.

Работа с None

Чтобы разобраться, как filter() работает с None, рассмотрим следующий пример:

list_ = [0, 1, 'Hello', '', None, [], [1,2,3], 0.1, 0.0, False]
print(list(filter(None, list_)))

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

В данном случае результатом работы будет список:

[1, 'Hello', [1, 2, 3], 0.1]

Мы видим, что такие элементы как 0, [], None, '', False были отфильтрованы, так как они являются элементами с нулевой длиной или численно равными 0, а значит являются ложными.

Применение filter() со списком словарей

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

Возьмём список книг в книжном магазине:

books = [
{"Title":"Angels and Demons", "Author":"Dan Brown", "Price":945},
{"Title":'Harry Potter and the Philosophers Stone', "Author":"J. K. Rowling", "Price":730},
{"Title":'Anna Karenina', "Author":'Leo Tolstoy', "Price":500},
{"Title":'Dead Souls', "Author":'Nikolai Gogol', "Price":400}
]

Отфильтруем книги по цене. Напишем функцию, которая получит все книги, которые стоят больше 500:

def cost(book):
    if book["Price"] > 500:
        return True
    else:
        return False

Тут все просто, функция проверяет стоимость каждой книги и возвращает True, если она удовлетворяет условию.

Выведем названия книг через цикл for:

filtered_object = filter(cost, books)
for row in filtered_object:
    print(dict(row)["Title"])

Результат:

Angels and Demons
Harry Potter and the Philosophers Stone

Фильтрация значений NaN

Предположим, что у нас есть выборка:

sample = [10.1, 8.3, 10.4, 8.8, float("nan"), 7.2, float("nan")]

В случае если мы захотим вычислить что-либо по такой выборке, например, среднее значение или отклонение, мы получим nan (не число).

Значения NaN могут появляться по разным причинам. Одной из альтернатив может быть их удаление из данных.

Воспользуемся для этого функцией isnan() из модуля math. Данная функция принимает число в качестве аргумента и возвращает логическое значение True, если это значение NaN, и False в обратном случае.

Так как функция filter добавляет в итератор элементы, которые получили значение функции True, мы в итоге получим только значения NaN. Чтобы это исправить напишем функцию, которая будет «разворачивать» результат функции isnan():

import math
import statistics as st
sample = [10.1, 8.3, 10.4, 8.8, float("nan"), 7.2, float("nan")]
def searcnan(x):
    if math.isnan(x):
        return False
    else: return True

Теперь, если мы вызовем

st.mean(filter(searcnan, sample))

То в результате получим 8.96.

В этом случае возможно поступить проще и вызвать функцию filterfalse(). Она такая же, как filter, но оставляет элементы с значением False:

from itertools import filterfalse
st.mean(filterfalse(math.isnan, sample))

Результат аналогичный: 8.96.

Заключение

Рассмотренная сегодня функция filter Python, как вы могли убедиться, может иметь множество разных применений. Мы рассмотрели основные из них. В процессе творческой работы вы сможете найти много других способов, как воспользоваться этой крутой функцией.

Telegram
VK
Скопировать ссылку
Как использовать Axios в React
Как использовать Axios в React
Как пользоваться SSH
Как пользоваться SSH

Зарегистрируйтесь и начните пользоваться
сервисами Timeweb Cloud прямо сейчас

15 лет опыта
Сосредоточьтесь на своей работе: об остальном позаботимся мы
165 000 клиентов
Нам доверяют частные лица и компании, от небольших фирм до корпораций
Поддержка 24/7
100+ специалистов поддержки, готовых помочь в чате, тикете и по телефону