Python: уроки, справочник и задачи

filter() в Python: как отфильтровать список

Раздел: Функции Python · Обновлено 31.10.2026

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

filter() в Python: как отфильтровать список
Фото: Robert Emperley from Strasbourg, Alsace, France / CC BY-SA 2.0, Wikimedia Commons
Содержание статьи
  1. Синтаксис filter()
  2. Фильтрация с обычной функцией
  3. Условие через lambda
    1. Отбор строк
    2. Списки словарей и словари
  4. Удаление пустых значений через filter(None)
  5. Результат это одноразовый итератор
  6. Что выбрать: filter() или генератор списка
  7. Частые вопросы
    1. Почему print(filter(...)) не показывает элементы?
    2. Меняет ли filter() исходный список?
    3. Можно ли передать в filter() несколько условий?
    4. Как отфильтровать строку и получить строку?

Синтаксис filter()

Функция встроенная, импортировать ничего не нужно. Она принимает два аргумента и возвращает итератор.

filter(function, iterable)

Элемент попадает в результат, если function(элемент) дает истинное значение. Порядок элементов сохраняется, сами элементы не изменяются. Если значения нужно преобразовать, а не отобрать, используется родственная функция map(), она разобрана в статье про zip и map.

Фильтрация с обычной функцией

Когда условие занимает несколько строк или пригодится в других местах программы, его оформляют отдельной функцией и передают в filter() по имени, без скобок.

def is_even(number):
    return number % 2 == 0

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = list(filter(is_even, numbers))
print(even_numbers)  # [2, 4, 6, 8, 10]

Функции не обязательно возвращать именно True или False. Подойдет любое значение: непустая строка и ненулевое число считаются истинными. Но явное булево значение делает код понятнее.

VOWELS = set("aeiou")

def is_vowel(letter):
    return letter.lower() in VOWELS

letters = ['a', 'b', 'd', 'E', 'i', 'j', 'o']
print(tuple(filter(is_vowel, letters)))  # ('a', 'E', 'i', 'o')

Результат можно превратить в любую коллекцию: список, кортеж, множество. Для проверки вхождения выгоднее держать гласные во множестве: поиск в нем быстрее, чем в списке.

Условие через lambda

Короткие условия удобно записывать прямо в вызове анонимной функцией. Это самый частый вариант использования filter(). Если синтаксис lambda пока незнаком, загляните в статью про лямбда функции.

temps = [-3, 5, -1, 8, 0, 12]
positive = list(filter(lambda t: t > 0, temps))
print(positive)  # [5, 8, 12]

Отбор строк

Со строками часто фильтруют по длине, началу или содержимому. Методы строк вызываются внутри lambda как обычно.

files = ['report.pdf', 'photo.jpg', 'notes.txt', 'scan.PDF']
pdfs = list(filter(lambda f: f.lower().endswith('.pdf'), files))
print(pdfs)  # ['report.pdf', 'scan.PDF']

words = ['кот', 'программа', 'дом', 'интерпретатор']
print(list(filter(lambda w: len(w) > 5, words)))
# ['программа', 'интерпретатор']

Списки словарей и словари

Если элементы это словари, условие обращается к нужному ключу. Сам словарь при переборе отдает ключи, поэтому для фильтрации пар используют items() и собирают результат обратно через dict().

students = [
    {'name': 'Анна', 'score': 85},
    {'name': 'Борис', 'score': 52},
    {'name': 'Вера', 'score': 78},
]
passed = filter(lambda s: s['score'] >= 60, students)
print([s['name'] for s in passed])  # ['Анна', 'Вера']

stock = {'яблоки': 12, 'груши': 0, 'сливы': 7}
available = dict(filter(lambda item: item[1] > 0, stock.items()))
print(available)  # {'яблоки': 12, 'сливы': 7}

Удаление пустых значений через filter(None)

Если первым аргументом передать None, функция оставит только истинные элементы. Это короткий способ очистить данные от пустых строк, нулей и None.

raw = [1, 'a', 0, False, True, '0', '', None, [], 3.5]
print(list(filter(None, raw)))  # [1, 'a', True, '0', 3.5]
Ложные значения (удаляются)Похожие, но истинные (остаются)
0, 0.0, False'0', -1
''' ' (пробел)
None'None'
[], (), {}, set()[0], [None]

Будьте внимательны с числами: filter(None, ...) выбросит и законный ноль. Если нужно убрать только None, пишите условие явно: filter(lambda x: x is not None, data).

Результат это одноразовый итератор

В Python 3 filter() возвращает не список, а объект filter. Он ленивый: элементы проверяются только в момент, когда их запрашивают. Поэтому print(filter(...)) показывает что-то вроде <filter object at 0x...>.

evens = filter(lambda x: x % 2 == 0, range(10))
print(list(evens))  # [0, 2, 4, 6, 8]
print(list(evens))  # []  итератор уже исчерпан

first_big = next(filter(lambda x: x > 1000, range(10**9)))
print(first_big)    # 1001

Ленивость дает два следствия. Пройти по результату можно только один раз, для повторного использования его сохраняют в список. Зато можно фильтровать огромные или бесконечные последовательности и строки большого файла, не загружая все в память. Подробнее о таком поведении написано в статье про итераторы.

Что выбрать: filter() или генератор списка

Тот же отбор можно записать генератором списка. Выбор чаще зависит от читаемости, чем от скорости.

numbers = range(1, 11)
via_filter = list(filter(lambda n: n % 3 == 0, numbers))
via_comp = [n for n in numbers if n % 3 == 0]
print(via_filter == via_comp)  # True
СитуацияЧто удобнее
Готовая функция-условие: str.isdigit, is_validfilter(str.isdigit, items)
Условие нужно записать на местеГенератор списка
Нужно и отобрать, и преобразовать[x * 2 for x in items if x > 0]
Большие данные без списка в памятиfilter() или выражение-генератор в круглых скобках

Синтаксис и возможности второго варианта описаны в статье про list comprehension. Для обратной задачи, когда нужны элементы, не прошедшие проверку, в стандартной библиотеке есть itertools.filterfalse(). Описание обеих функций есть в документации Python.

Частые вопросы

Короткие ответы на вопросы, которые задают при знакомстве с filter().

Почему print(filter(...)) не показывает элементы?

Функция возвращает ленивый итератор, а не список. Оберните результат в list() или переберите его циклом for.

Меняет ли filter() исходный список?

Нет, исходная коллекция остается прежней. Результат нужно присвоить новой переменной или той же самой: items = list(filter(...)).

Можно ли передать в filter() несколько условий?

Функция принимает одно условие, но внутри него можно объединить проверки через and и or: filter(lambda x: x > 0 and x % 2 == 0, data). Другой вариант: вложить один filter() в другой.

Как отфильтровать строку и получить строку?

Отобранные символы собирают методом join(): ''.join(filter(str.isdigit, 'a1b2c3')) вернет '123'.