Содержание
Краткая памятка по использованию filter() в Python
- Запомните, что filter() возвращает итератор, а не список.
- Используйте filter(None, iterable) для удаления всех «ложных» элементов.
- Для простых условий предпочитайте list comprehension.
- Для сложных условий создавайте именованную функцию-предикат.
- Используйте лямбда-функции для коротких, однострочных условий.
- Комбинируйте filter() с map() для построения функциональных пайплайнов.
- При работе с большими данными используйте ленивую фильтрацию для экономии памяти.
- Для фильтрации словарей проверяйте значения по ключам внутри предиката.
- Избегайте мутации исходного списка внутри filter().
- Помните, что filter() можно использовать с любым итерируемым объектом.
- Для фильтрации NaN используйте math.isnan() или pandas.isna().
- При необходимости сразу материализуйте результат в список с помощью list().
Синтаксис
Чтобы получить значения, которые были оценены как False, используется функция:
Функция более эффективна по времени выполнения, чем цикл for, через который тоже можно сделать фильтрацию. Другим преимуществом является то, что функция filter возвращает итератор, что является более эффективным использованием памяти. Это было введено для. В версии python 2 возвращает объект типа list.
filter Pythonfilter в python 3функция фильтр
Разобрав основы функции, давайте посмотрим, на различных примерах.
как работает filter()
Использование filter() с функцией
Первый аргумент в filter() — это функция, которую мы используем для решения о включении или фильтрации каждого элемента. Функция вызывается один раз для каждого элемента в итерируемом объекте, переданном как второй аргумент и каждый раз при возвращении False значение сбрасывается. Поскольку этот аргумент является функцией, мы можем либо передать обычную функцию, либо использовать функции lambda, особенно когда выражение является менее сложным.
С помощью списка ниже можно включить функцию lambda с выражением, по которому мы хотим оценить каждый элемент из списка:
Чтобы отфильтровать этот список для поиска названий наших аквариумных созданий, начинающихся с гласной, мы можем запустить следующую функцию lambda:
Здесь мы заявляем в нашем списке элемент в качестве x. Затем мы настроим наше выражение для доступа к первому символу каждой строки (или символу «нуль»), то есть x[0]. Установка нижнего регистра в каждом из названий обеспечит соответствие букв строке в нашем выражении, ‘aeiou’.
Наконец, мы передадим итерируемому объекту creature_names. Как и в предыдущем разделе, мы применяем list() к результату, чтобы создать список из возвратов итератора filter().
Наша функция names_vowels определяет выражение, которое мы будем применять для фильтра creature_names.
В целом, функции lambda достигают того же результата с filter(), что и при использовании обычной функции. Необходимость определения обычной функции растет по мере увеличения сложности выражений для фильтрации наших данных, что, скорее всего, будет способствовать улучшению читабельности нашего кода.
Применение обычной функции в качестве фильтра последовательности.
num = list(range(0, 27)) # определяем отдельную функцию которая # отбирает четные элементы > 18. def ff(x): if x > 18 and not x % 2: return True else: return False >>> f = filter(ff, num) >>> list(f) # [20, 22, 24, 26]
Когда условие сложное и требует промежуточных переменных
out = [] for row in rows: if not: continue score = compute_score(row) if score >= 0.8: ((row, score))
filter() здесь обычно делает код менее прозрачным, потому что всё приходится прятать в функцию/лямбду.
Когда вы хотите переиспользуемый предикат (функцию условия)
Если условие уже оформлено как функция (или метод), filter() может читаться хорошо.
def is_even(x: int) -> bool: return x % 2 == 0 evens = list(filter(is_even, [1, 2, 3, 4, 5, 6]))
Паттерн 3: Составные условия — лучше именованный предикат
def ok(x: int) -> bool: return x > 0 and x % 3 == 0 and x < 100 filtered = list(filter(ok, range(-10, 150)))
Применение filter() с пользовательской функцией
В данном случае мы передаем в filter() пользовательскую функцию (filter_num) и список чисел — numbers.
Наша пользовательская функция проверяет каждый элемент списка на нечетность. Для этого, как мы знаем, должен быть ненулевой остаток при делении на 2. В случае если число нечетное, функция возвращает True, а значит этот элемент попадает в итоговый итератор.
Так как функция filter() возвращает объект с типом — <class ‘filter’>, для получения самого результата необходимо преобразовать вывод. Например, мы преобразовали его в объект типа list (список). Этот пример возможно также реализовать с использованием лямбда-функции:
Она принимает на вход 2 массива, которые нужно проверить. После этого с помощью лямбда-функции находятся общие элементы.
Фильтр нечетных чисел
В этом примере в качестве итерируемого объекта — список числовых значений
И есть функция, которая отфильтровывает нечетные числа. Она передается в качестве первого аргумента вызову 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 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 ll = list2 out_filter = list(filter(filter_duplicate, list1)) ll = list1 out_filter += list(filter(filter_duplicate, list2)) print(«Отфильтрованный список:», out_filter)
Как и ожидалось, код вывел разницу двух списков. Однако это лишь примеры работы функции.
Пересечение двух массивов
В этом примере создадим лямбда-выражение, а затем применим функцию фильтрации для поиска общих элементов в них.
arr1 = [‘p’,’y’,’t’,’h’,’o’,’n’,’ ‘,’3′,’.’,’0′] arr2 = [‘p’,’y’,’d’,’e’,’v’,’ ‘,’2′,’.’,’0′]
Создадим lambda-функцию, которая будет отфильтровывать разницу и возвращать общие элементы.
«»» Программа для поиска общих элементов в двух списках с использованием функции lambda и filter() «»» arr1 = [‘p’,’y’,’t’,’h’,’o’,’n’,’ ‘,’3′,’.’,’0′] arr2 = [‘p’,’y’,’d’,’e’,’v’,’ ‘,’2′,’.’,’0′] def interSection(arr1, arr2): out = list(filter(lambda it: it in arr1, arr2)) return out if __name__ == «__main__»: out = interSection(arr1, arr2) print(«Отфильтрованный список:», out)
Отфильтровать стоп-слова из строки
string_to_process = «Сервис по поиску работы и сотрудников HeadHunter опубликовал подборку высокооплачиваемых вакансий в России за август.»
«»» Программа для удаления стоп-слов из строки используя функцию filter() «»» list_of_stop_words = [«в», «и», «по», «за»] string_to_process = «Сервис по поиску работы и сотрудников HeadHunter опубликовал подборку высокооплачиваемых вакансий в России за август.» 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 опубликовал подборку высокооплачиваемых вакансий России август.
Использование лямбда-выражений с filter()
Лямбда-выражение в Python также работает как встроенная функция. Таким образом ее можно указать вместо функции в качестве аргумента при вызове filter() и избавиться от необходимости написания отдельной функции для фильтрации.
Когда вам нужен список и вы всё равно материализуете результат
Если вы в итоге делаете list(filter(…)), то преимущество ленивости исчезает. Тогда часто удобнее comprehension.
Предпочитайте именованные функции/operator вместо "толстых" lambda
Если предикат сложный — либо дайте ему имя, либо вынесите в функцию, либо используйте уже готовые средства.
def is_good_user(u) -> bool: return u.is_active and >= 18 and u.email_verified good = filter(is_good_user, users)
Применение filter() с лямбда-функцией
Функция filter также может принимать на вход лямбда-функции. Например, создадим детектор палиндромов:
Лямбда-функция проверяет, равно ли слово самому себе, написанному наоборот. Если это так, то возвращает True.
Использование None с filter()
Мы можем передать None в качестве первого аргумента filter(), чтобы исключить из возвращенного фильтра итератора любые значения, которые Python считает «ложными». Обычно Python считает все значения длиной 0 (например пустой список или пустую строку) или числовой эквивалент 0 ложными, отсюда использование термина «ложный».
В следующем случае мы хотим фильтровать наш список так, чтобы отображались только номера номера емкостей в нашем аквариуме:
Мы используем функцию filter() с None и передадим список aquarium_tanks в качестве нашего итерируемого объекта. Поскольку мы передали None в качестве первого аргумента, проверим, считаются ли элементы в нашем списке ложными.
Затем обернем filtered_tanks в функцию list() для возврата списка для filtered_tanks при печати.
Здесь мы видим, что вывод отображает только целые значения. Все элементы, оцененные как False, равные 0 по длине, были удалены filter():
Примечание. Если мы не используем list() и печатаем filtered_tanks, мы получим объект фильтра вроде <filter object at 0x7fafd5903240>. Объект фильтра является итерируемым, поэтому мы можем пройтись по нему с помощью for или использовать list() для превращения его в список, который мы здесь делаем, так как это хороший способ проверки результатов.
C None мы использовали filter() для быстрого удаления элементов из нашего списка, которые считались ложными.
Описание:
Функция filter() отбирает/фильтрует элементы переданного объекта iterable при помощи пользовательской функции func.
Функция filter() принимает в качестве аргументов пользовательскую функцию и объект, элементы которого следует отфильтровать (может быть последовательностью или объектом поддерживающий итерирование).
- Если фильтрующая функция func вернёт False, то элемент последовательности iterable не попадёт в результат выполнения функции filter().
- Если фильтрующая функция func вернет None, то считается что требуется применить тождественное действие (item for item in iterable if item), таким образом все элементы, оцениваемые как False будут отфильтрованы.
Чтобы получить результат из элементов оцененных пользовательской функцией как False, воспользуйтесь ().
Из всего сказанного можно сделать вывод, что для успешного использования функции filter() необходимо в результате каких то вычислений/сравнений над каждым элементом передаваемой последовательности получать True или 1 для элементов которые нужно отобрать и False или 0 для элементов, которые нужно отбросить.
При несложных вычислениях фильтрации, легче всего такое поведение можно получить при помощи лямбда-функции, используя в них стандартные функции или методы, возвращающие bool значения, операции сравнения, оператор вхождения in и оператор идентичности is.
Если необходимо произвести более сложные вычисления фильтрации, то для этого необходимо определить обычную функцию и передать ее в качестве первого аргумента функции filter().
Когда нужно просто "оставить только непустые/не-None" элементы (truthy)
raw = [«Alice», «», «Bob», None, » «, «Chris»] # Важно: строка » » truthy, так что она останется. Если надо убрать «пустые после strip» — см. ниже. non_empty = list(filter(None, raw)) # [«Alice», «Bob», » «, «Chris»]
Обоснование: коротко и выразительно, если вас устраивает именно truthiness-фильтр.
Паттерн 2: Убрать только None (правильный способ)
values = [None, 10, 0, None, 5] not_none = list(filter(lambda x: x is not None, values)) # или: not_none2 = [x for x in values if x is not None]
Работа с None
Если в качестве функции в filter() передается None, то будут отфильтрованы все элементы, которые имеют логическое значение False (являются ложными сами по себе).
Мы видим, что такие элементы как 0, [], None, », False были отфильтрованы, так как они являются элементами с нулевой длиной или численно равными 0, а значит являются ложными.
Функция filter без функции
Да, можно вызывать функцию filter() без передачи ей функции в качестве первого аргумента. Вместо этого нужно указать None.
В таком случае фильтр уберет те элементы, результат исполнения которых равен False. Возьмем в качестве примера следующую последовательность.
«»» Вызов функции filter() без функции «»» bools = [‘bool’, 0, None, True, False, 1, 1-1, 2%2] out = filter(None, bools) for iter in out: print(iter)
Теперь вы должны лучше понимать принцип работы функции filter() в Python.
Применение filter() со списком словарей
Функция также может работать с более сложными структурами данных. Например, у нас есть список словарей, и мы хотим выполнять итерации не только по каждому элементу в списке, но и по каждой паре ключ-значение в этом словаре.
Тут все просто, функция проверяет стоимость каждой книги и возвращает True, если она удовлетворяет условию.
Паттерн 1: Отфильтровать объекты по состоянию
from dataclasses import dataclass @dataclass class User: name: str is_active: bool users = [User(«A», True), User(«B», False), User(«C», True)] active_users = list(filter(lambda u: u.is_active, users)) # Альтернатива (часто читаемее): active_users2 = [u for u in users if u.is_active]
Использование filter() со списком словарей
Когда у нас имеется более сложная структура данных, мы все еще можем использовать filter() для оценки каждого из элементов. Например, если у нас есть список словарей, мы не только хотим выполнить итерацию по каждому элементу в списке — одному из словарей, — но мы также хотим выполнить итерацию по каждой паре key:value в словаре, чтобы оценить все данные.
Например, допустим, у нас есть список всех созданий в аквариуме с различными данными о каждом из них:
aquarium_creatures = [{«name»: «sammy», «species»: «shark», «tank number»: «11», «type»: «fish»}, {«name»: «ashley», «species»: «crab», «tank number»: «25», «type»: «shellfish»}, {«name»: «jo», «species»: «guppy», «tank number»: «18», «type»: «fish»}, {«name»: «jackie», «species»: «lobster», «tank number»: «21», «type»: «shellfish»}, {«name»: «charlie», «species»: «clownfish», «tank number»: «12», «type»: «fish»}, {«name»: «olly», «species»: «green turtle», «tank number»: «34», «type»: «turtle»}]
Мы хотим фильтровать эти данные по строке поиска, которую мы предоставили функции. Для доступа filter() к каждому словарю и каждому элементу в словарях, мы создадим вложенную функцию, например:
def filter_set(aquarium_creatures, search_string): def iterator_func(x): for v in (): if search_string in v: return True return False return filter(iterator_func, aquarium_creatures)
Мы определяем функцию filter_set(), которая принимает aquarium_creatures и search_string в качестве параметров. В filter_set() мы передадим iterator_func() в качестве функции filter(). Функция filter_set() вернет итератор, полученный от filter().
iterator_func() принимает x в качестве аргумента, представляющего элемент в нашем списке (т.е. единый словарь).
Затем цикл for получит доступ к каждой паре key:value в наших словарях, а затем будет использовать условное выражение для проверки того, есть ли search_string в v, представляя значение.
Как и в предыдущих примерах, если выражение оценивает значение как True, функция добавляет элемент в объект фильтра. Оно вернется после выполнения функции filter_set(). Мы расположим return False за пределами нашего цикла для проверки каждого элемента в каждом словаре вместо получения результатов после проверки одного первого словаря.
Мы вызовем filter_set() с нашим списком словарей и строкой поиска, для которых мы хотим найти совпадения:
После выполнения функции мы сохраним объект фильтра в переменной filtered_records, которую мы превращаем в список и печатаем:
Мы отфильтровали список словарей по строке поиска 2. Мы видим, что вернулись три словаря, включающие номер емкости с 2. Использование нашей собственной вложенной функции позволило нам получить доступ к каждому элементу выполнить эффективную проверку относительно каждой строки поиска.
Применение filter() с фильтрацией выбросов в выборке
Импортируем библиотеку для статистических вычислений и задаем нормально распределенную выборку с несколькими выбросами.
В выборках с нормальным распределением зачастую выбросы определяются как значения, которые отличаются от среднего более чем на 2 стандартных отклонения.
Фильтрация значений NaN
В случае если мы захотим вычислить что-либо по такой выборке, например, среднее значение или отклонение, мы получим nan (не число).
Значения NaN могут появляться по разным причинам. Одной из альтернатив может быть их удаление из данных.
Воспользуемся для этого функцией isnan() из модуля math. Данная функция принимает число в качестве аргумента и возвращает логическое значение True, если это значение NaN, и False в обратном случае.
Так как функция filter добавляет в итератор элементы, которые получили значение функции True, мы в итоге получим только значения NaN. Чтобы это исправить напишем функцию, которая будет «разворачивать» результат функции isnan():
В этом случае возможно поступить проще и вызвать функцию filterfalse(). Она такая же, как filter, но оставляет элементы с значением False:
Когда нужна ленивая фильтрация (не загружать всё в память)
filter() не создаёт список сразу — он отдаёт элементы по мере итерации. Это полезно для:
- больших коллекций,
- потоков (файл, генератор),
- пайплайнов обработки данных.
def is_valid(line: str) -> bool: return ()!= «» and not ().startswith(«#») with open(«», encoding=»utf-8″) as f: for line in filter(is_valid, f): handle(line)
Обоснование: вы не держите все строки в памяти и не строите промежуточные списки.
Когда фильтр — часть функционального пайплайна
nums = range(1, 1_000_000) # Проверить, есть ли среди чисел кратные 7 и 11 exists = any(filter(lambda x: x % 7 == 0 and x % 11 == 0, nums))
Паттерн 4: Фильтрация строк файла "на лету"
def meaningful(line: str) -> bool: s = () return bool(s) and not («#») with open(«», encoding=»utf-8″) as f: for line in filter(meaningful, f): process(line)
Паттерн 5: Фильтрация вместе с map (пайплайн)
def to_int_or_none(s: str) -> int | None: s = () if not s: return None try: return int(s) except ValueError: return None raw = [«10″, » «, «x», «20», «0»] nums = filter(lambda x: x is not None, map(to_int_or_none, raw)) print(list(nums)) # [10, 20, 0]
Ошибка: ожидать список, а получить итератор
filter возвращает итератор — если вы попытаетесь индексировать, будет ошибка.
Облачные серверы
Масштабируемые вычислительные ресурсы по всему миру с почасовой оплатой.
Часто задаваемые вопросы о работе функции filter в Python
Вопрос: Что возвращает функция filter()?
Ответ: Функция filter() возвращает итератор (объект filter), а не список. Чтобы получить список, нужно обернуть результат в list().
Вопрос: В чем разница между filter() и list comprehension?
Ответ: Оба подхода фильтруют элементы. List comprehension обычно более читаем для простых условий, а filter() лучше подходит для функционального стиля и работы с уже существующими функциями-предикатами.
Вопрос: Можно ли использовать filter() без функции?
Ответ: Да, если передать None вместо функции, filter() удалит все элементы, которые в булевом контексте являются False (0, None, пустые строки, пустые списки и т.д.).
Вопрос: Как работает filter() с лямбда-функциями?
Ответ: Лямбда-функция передается как первый аргумент и определяет условие фильтрации. Например: filter(lambda x: x > 0, numbers).
Вопрос: Что такое ленивая фильтрация в контексте filter()?
Ответ: Это означает, что filter() не вычисляет все элементы сразу, а генерирует их по требованию при итерации. Это экономит память при работе с большими данными.
Вопрос: Как отфильтровать значения NaN с помощью filter()?
Ответ: Можно использовать функцию math.isnan() или pandas.isna() в качестве предиката, чтобы исключить или оставить NaN значения.
Вопрос: Можно ли использовать filter() со списком словарей?
Ответ: Да, filter() отлично работает со списком словарей. Предикат проверяет значения по ключам, например: filter(lambda d: d[‘age’] > 18, people).
Вопрос: В чем преимущество filter() перед циклом for?
Ответ: filter() делает код более лаконичным и декларативным, особенно в сочетании с map() и reduce() в функциональном пайплайне.
Вопрос: Как отфильтровать повторяющиеся значения из двух списков?
Ответ: Можно использовать filter() с лямбда-функцией, которая проверяет вхождение элемента из первого списка во второй: filter(lambda x: x in list2, list1).
Вопрос: Что произойдет, если передать в filter() неитерируемый объект?
Ответ: Python вызовет ошибку TypeError, так как filter() ожидает итерируемый объект (список, кортеж, строку и т.д.) в качестве второго аргумента.

























