Filter: примеры (PYTHON)
filter(function, iterable): filter objectФункция filter в Python
Функция filter() применяется для фильтрации элементов итерируемого объекта с использованием заданной функции-предиката. Она возвращает итератор, содержащий только те элементы исходной последовательности, для которых функция-предикат возвращает истинное значение.
Использование функции filter() актуально в ситуациях, когда требуется выбрать подмножество данных по определенному критерию без изменения самих элементов.
Синтаксис функции: filter(function, iterable).
- function: Функция-предикат, которая применяется к каждому элементу итерируемого объекта. Может принимать одно значение и возвращать
TrueилиFalse. Если передано значениеNone, фильтрация выполняется на основе истинности самих элементов (эквивалентноbool(element)). - iterable: Любой итерируемый объект (список, кортеж, строка, словарь, множество, генератор), элементы которого подвергаются проверке.
- Возвращаемое значение: Объект типа
filter(итератор). Для получения привычных структур данных (списка, кортежа) требуется явное преобразование с помощьюlist()илиtuple().
Простые примеры использования
Пример с функцией-предикатом:
def is_positive(num):
return num > 0
numbers = [-2, -1, 0, 1, 2, 3]
result = filter(is_positive, numbers)
print(list(result))[1, 2, 3]Пример с использованием None для отсеивания ложных значений:
mixed_values = [0, 1, False, True, '', 'hello', [], [1,2]]
result = filter(None, mixed_values)
print(list(result))[1, True, 'hello', [1, 2]]Пример с lambda-функцией:
numbers = [1, 2, 3, 4, 5, 6]
result = filter(lambda x: x % 2 == 0, numbers)
print(list(result))[2, 4, 6]Пример фильтрации строк:
words = ['apple', 'banana', 'cherry', 'date']
result = filter(lambda w: 'a' in w, words)
print(list(result))['apple', 'banana', 'date']Похожие инструменты в Python
Генераторы списков (List Comprehensions): Предлагают более компактный и часто более производительный синтаксис для простой фильтрации. [x for x in iterable if condition(x)] эквивалентно list(filter(lambda x: condition(x), iterable)). Генераторы списков обычно предпочтительнее для простых условий и когда сразу нужен список.
Функция map(): Применяет функцию преобразования ко всем элементам, а не фильтрует. Может комбинироваться с filter() через генераторы.
itertools.filterfalse(): Из модуля itertools выполняет противоположную операцию - возвращает элементы, для которых функция-предикат возвращает False.
Цикл for с условием: Явный цикл предоставляет максимальную гибкость для сложной логики фильтрации, но менее лаконичен.
Встроенная функция bool(): Часто используется как предикат по умолчанию при фильтрации истинных значений.
Аналоги в других языках программирования
JavaScript: Метод Array.prototype.filter(). Работает аналогично, но является методом массива и возвращает новый массив.
const numbers = [1, 2, 3, 4];
const result = numbers.filter(x => x % 2 === 0);
console.log(result); // [2, 4]PHP: Функция array_filter(). Фильтрует элементы массива с помощью callback-функции.
$numbers = [1, 2, 3, 4];
$result = array_filter($numbers, fn($x) => $x % 2 == 0);
print_r($result); // Array ( [1] => 2 [3] => 4 )Java: Stream API с методом filter(). Работает с потоками данных и требует терминальной операции для получения результата.
List numbers = Arrays.asList(1, 2, 3, 4);
List result = numbers.stream()
.filter(x -> x % 2 == 0)
.collect(Collectors.toList());
// result = [2, 4] C#: Метод расширения Where() из LINQ. Работает с коллекциями и возвращает отфильтрованную последовательность.
var numbers = new List {1, 2, 3, 4};
var result = numbers.Where(x => x % 2 == 0).ToList();
// result = [2, 4] SQL: Оператор WHERE в запросах SELECT. Выполняет фильтрацию записей на уровне базы данных.
SELECT * FROM table WHERE column % 2 = 0;Go: Явная фильтрация через цикл, так как в языке нет встроенной функции высшего порядка для фильтрации срезы.
Kotlin: Метод filter() для коллекций. Аналогичен JavaScript, но с лучшей интеграцией в систему типов.
val numbers = listOf(1, 2, 3, 4)
val result = numbers.filter { it % 2 == 0 }
// result = [2, 4]Lua: Отсутствует встроенная функция, реализуется через циклы или внешние библиотеки.
Распространенные ошибки
Забытое преобразование итератора: Попытка работы с объектом filter как с последовательностью.
result = filter(lambda x: x > 0, [-1, 0, 1])
print(result[0]) # TypeError: 'filter' object is not subscriptableTypeError: 'filter' object is not subscriptableОднократное использование итератора: Объект filter потребляется при первом проходе.
f = filter(lambda x: x > 0, [1, -2, 3])
print(list(f)) # [1, 3]
print(list(f)) # [][1, 3]
[]Функция-предикат без возврата булева значения: Функция возвращает не bool, а другое значение, которое все равно интерпретируется как истинность.
result = filter(lambda x: x, [0, 1, 2, 3])
print(list(result)) # [1, 2, 3], так как 0 - False, остальные - TrueИзменение исходного итерируемого объекта во время фильтрации: Может привести к непредсказуемому поведению.
items = [1, 2, 3, 4]
result = filter(lambda x: x > 2, items)
items.remove(3)
print(list(result)) # Результат может быть неожиданнымИзменения в последних версиях
В Python 3 функция filter() всегда возвращает итератор (объект типа filter), а не список, как это было в Python 2. Это изменение улучшило производительность за счет ленивых вычислений и экономии памяти.
Начиная с Python 3.8, в справочной документации были уточнены рекомендации по использованию генераторов списков как более понятной альтернативы для простых случаев фильтрации.
Специфика поведения с None в качестве функции осталась неизменной: фильтрация на основе истинности значений.
Расширенные примеры применения
Фильтрация словарей по значениям:
data = {'a': 1, 'b': 0, 'c': 3, 'd': 0}
result = dict(filter(lambda item: item[1] != 0, data.items()))
print(result) # {'a': 1, 'c': 3}Фильтрация с использованием метода объекта:
class Person:
def __init__(self, age):
self.age = age
def is_adult(self):
return self.age >= 18
people = [Person(15), Person(20), Person(17), Person(25)]
adults = list(filter(Person.is_adult, people))
print([p.age for p in adults]) # [20, 25]Цепочка фильтров:
numbers = range(20)
filtered = filter(lambda x: x % 2 == 0, numbers) # Четные
filtered = filter(lambda x: x % 3 == 0, filtered) # Кратные 3
print(list(filtered)) # [0, 6, 12, 18]Фильтрация с сохранением индексов через enumerate:
items = ['apple', 'banana', 'cherry', 'date']
filtered = filter(lambda x: 'a' in x[1], enumerate(items))
indices, values = zip(*filtered) if filtered else ((), ())
print(list(indices)) # [0, 1, 3]
print(list(values)) # ['apple', 'banana', 'date']Использование с itertools.islice для ограничения результатов:
from itertools import islice
numbers = (x for x in range(1000) if x % 7 == 0)
result = islice(filter(lambda x: x % 3 == 0, numbers), 5)
print(list(result)) # Первые 5 чисел, кратных 21Фильтрация с обработкой исключений в предикате:
def safe_divide(x):
try:
return 10 / x > 2
except ZeroDivisionError:
return False
values = [0, 1, 2, 3, 4, 5]
result = list(filter(safe_divide, values))
print(result) # [1, 2, 3, 4]Фильтрация по нескольким условиям:
import operator
from functools import partial
conditions = [lambda x: x >= 0, lambda x: x % 2 == 0, lambda x: x < 10]
numbers = range(-5, 15)
for cond in conditions:
numbers = filter(cond, numbers)
print(list(numbers)) # [0, 2, 4, 6, 8]Фильтрация None-значений из списка с сохранением позиций:
data = [1, None, 3, None, 5]
result = list(filter(lambda x: x is not None, data))
print(result) # [1, 3, 5]