Функция filter - фильтрация последовательностей

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

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

В примере ниже создается функция func(), которая возвращает 1, если ей передан аргумент больше нуля, и 0 во всех остальных случаях. Когда эту функцию применяют для списка a, то получается объект-итератор из положительных элементов a.

>>> a = [1, -4, 6, 8, -10]
>>> def func(x):
...     if x > 0:
...             return 1
...     else:
...             return 0
...
>>> b = filter(func, a)
>>> b = list(b)
>>> b
[1, 6, 8]

Когда к итератору происходит обращение, из него извлекаются элементы. После этого получить их из итератора уже невозможно. Поэтому в данном случае используется функция list(), чтобы преобразовать итератор к списку. Иначе получилось бы так:

>>> b = filter(func, a)
>>> for i in b:
...     print(i)
...
1
6
8
>>> for i in b:
...     print(i)
...
>>>

Как видно из примера при повторном обращении объект уже ничего не содержит.

Теперь посмотрим на такой вариант:

>>> a = [-1, 0, 1, 0, 0, 1, 0, -1]
>>> b = list(filter(None,a))
>>> b
[-1, 1, 1, -1]

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

>>> s = ['a','','d','cc',' ']
>>> ss = list(filter(None, s))
>>> ss
['a', 'd', 'cc', ' ']

Пустая строка не прошла через фильтр, а вот строка, содержащая исключительно символ пробела, не пуста и возвращает True.

Еще один пример - из строки фильтруются числа:

>>> def numbs(x):
...     if '0' <= x <= '9':
...             return 1
...     else:
...             return 0
...
>>> s = "5a 3 k 99 d00"
>>> for i in filter(numbs,s):
...     print(i)
...
5
3
9
9
0
0