Курс по Python: https://stepik.org/course/100707
На прошлом занятии мы с вами детально познакомились с функцией map(). Здесь же
будем говорить о похожей функции filter():
filter(func,
*iterables)
которая служит
для фильтрации (отбора) элементов указанного итерированного объекта.
Работает она очень
просто. Если функция func возвращает для текущего значения
элемента True, то он будет
возвращен, а при False – отброшен. Например, у нас имеется
список из целых чисел:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
и мы хотим
выбрать из него только четные значения. Для этого запишем функцию filter(), следующим
образом:
b = filter(lambda x: x % 2 == 0, a)
print(b)
После запуска
программы, видим, что переменная b ссылается на специальный объект filter. В
действительности, это итератор, который можно перебрать с помощью функции next():
print(next(b))
print(next(b))
В результате,
увидим в консоли первые два четных значения из списка. Переберем их все с
помощью цикла for:
for x in b:
print(x, end=" ")
Или, можно
сформировать новый список с помощью функции list():
Или кортеж:
И так далее.
Можно перебрать итератор любыми известными нам функциями и операторами.
Иногда алгоритм
обработки текущего значения может быть нетривиальным и записать его в лямбда-функцию
довольно сложно. Ну, например, проверить, является ли число простым или нет.
Напомню, что простым называется любое натуральное число, которое делится только
на себя и на единицу. Такую проверку лучше вынести в отдельную функцию:
def is_prost(x):
d = x-1
if d < 0:
return False
while d > 1:
if x % d == 0:
return False
d -= 1
return True
А, затем, указать
ее в filter():
На выходе
получим только простые числа из списка. Конечно, это не самый лучший способ
нахождения простых чисел, но как пример функции для filter() вполне
подходит.
Функцию filter можно применять
с любыми типами данных, например, строками. Пусть у нас имеется вот такой
кортеж:
lst = ("Москва", "Рязань1", "Смоленск", "Тверь2", "Томск")
b = filter(str.isalpha, lst)
for x in b:
print(x)
и мы вызываем
метод строк isalpha(), который
возвращает True, если в строке
только буквенные символы. В результате в консоли увидим:
Москва Смоленск
Тверь Томск
Вложенные вызовы функции filter()
Так как функция filter() возвращает
итератор и в качестве второго аргумента также можно указывать любой итерируемый
объект, то мы можем одну функцию filter() вложить в другую:
Например, первая
(вложенная) функция filter() будет формировать простые числа, а
вторая (внешняя) выбирать из простых чисел только нечетные. В нашей программе
для этого достаточно прописать еще одну строчку:
b2 = filter(lambda x: x % 2 != 0, b)
и вывести
полученный список:
Или, то же самое
можно реализовать и так:
b2 = filter(lambda x: x % 2 != 0, filter(is_prost, a))
Мы здесь вторым
аргументом передаем результат работы вложенной функции filter(). И таких
вложений можно делать сколько угодно. Хотя на практике, как правило, все эти
вложения можно легко свести к одному простому вызову функции filter(), сформировав
более сложное условие. Обычно, так и поступают. То есть, опять же, в нашем
случае вместо этой вложенности можно немного модифицировать саму функцию is_prost(), следующим
образом:
def is_prost(x):
d = x-1
if d < 0 or x % 2 == 0:
return False
while d > 1:
if x % d == 0:
return False
d -= 1
return True
Мы здесь вначале
прописали составное условие if d < 0 or x % 2 == 0,
которое сразу возвратит False для четного значения x. И при этом,
программа будет работать быстрее.
Вот так работает
и используется функция filter() для отбора определенных
значений из итерируемых объектов. Для закрепления этого материала пройдите
практические задания и переходите к следующему уроку.
Курс по Python: https://stepik.org/course/100707