Курс по Python: https://stepik.org/course/100707
Это занятие будет посвящено, так
называемым, анонимным или, их еще называют, lambda функциям. Что
это за функции и почему их называют анонимными? Сейчас вы все узнаете!
Лямбда функция
определяется по очень простому синтаксису:
lambda param_1, param_2, …: команда
и записывается в
программе, как оператор. Например, вот так можно определить лямбда-функцию для
сложения двух значений:
У нее два
параметра a и b, а затем, через
двоеточие написано, что с ними нужно сделать. Полученное значение будет
автоматически возвращено этой функцией. И, обратите внимание, у этой функции
нет имени, поэтому она и называется анонимной. Но как тогда ее вызывать? Для
этого объект-функцию, который создает лямбда-функция, нужно присвоить
какой-либо переменной:
И уже через нее
вызывать саму функцию:
В чем
особенность такого определения функции? Зачем ее придумали и почему бы не
пользоваться обычными функциями? У нее есть одно принципиальное отличие от
ранее рассматриваемых нами функций – она может быть записана как элемент любой
конструкции языка Python. Например, прямо как элемент списка:
a = [4, 5, lambda: print("lambda"), 7, 8]
Мы здесь
описываем лямбда-функцию и сразу же передаем ее в список. С обычными функциями
так не получится. Они должны быть объявлены заранее и только потом мы могли бы
передать ссылку на нее в список. Если мы сейчас обратимся к третьему элементу
этого списка:
то увидим ссылку
на объект-функцию. И, как мы уже знаем, чтобы ее запустить на выполнение нужно
прописать оператор – круглые скобки:
И,
действительно, функция была выполнена и в консоли отобразилось сообщение.
Конечно,
анонимные функции, обычно, не используются для вывода какой-либо информации.
Как правило, они выполняют определенную команду и возвращают полученный
результат. Для ясности, приведу такой пример. Предположим, у нас имеется
список:
lst = [5, 3, 0, -6, 8, 10, 1]
и мы хотим
написать функцию, которая бы выбирала значения из этого списка по определенному
критерию (фильтру):
def get_filter(a, filter=None):
if filter is None:
return a
res = []
for x in a:
if filter(x):
res.append(x)
return res
Здесь второй
параметр filter – это ссылка на
другую функцию, которая будет отбирать значения из списка lst. Если вызвать
ее только с первым аргументом:
lst = [5, 3, 0, -6, 8, 10, 1]
r = get_filter(lst)
print(r)
То увидим в
консоли тот же самый список без изменений. Но, если вторым аргументом передать
вот такую лямбда-функцию:
r = get_filter(lst, lambda p: p % 2 == 0)
то возвратится
новый список, состоящий только из четных значений. Как это произошло? В этом
примере второй параметр filter функции get_filter стал ссылаться
на лямбда-функцию. Эта функция возвращает True для четных
значений и False – для нечетных.
Соответственно, в цикле при переборе элементов списка, условие будет срабатывать
только для четных значений и только они будут добавляться в список res. Видите, как
удобно и наглядно можно использовать лямбда-функции в программировании? Если бы
их не существовало, нам бы пришлось объявлять отдельную функцию:
def even(p):
return p % 2 == 0
А, затем,
передавать ссылку на нее:
r = get_filter(lst, even)
Согласитесь, это
несколько более трудоемкий и менее удобный вариант? Мало того, если нам
понадобится быстро изменить фильтр, то достаточно поправить реализацию
анонимной функции, например, для выделения только положительных чисел:
r = get_filter(lst, lambda p: p > 0)
Быстро и просто!
В этом одно из удобств этих анонимных функций – их можно сразу прописать в
нужном месте программы.
Однако, у таких
функций есть одно существенное ограничение – в них можно прописать только одну
конструкцию языка Python, то есть, выполнить только одну
какую-либо команду. Также нельзя объявлять анонимные функции в несколько строк:
вызовет
синтаксическую ошибку. Наконец, в лямбда-функциях нельзя использовать оператор
присваивания:
Это также
вызовет синтаксическую ошибку. Здесь мы можем лишь создавать новый объект на
основе входных параметров (или глобальных, общих переменных программы):
s = lambda a: a + 1
s(1)
p = lambda: "hello python"
p()
либо просто возвращать
ссылки на уже существующие объекты:
На этом мы
завершим текущее занятие. Для закрепления материала пройдите практические
задания и переходите к следующему уроку.
Курс по Python: https://stepik.org/course/100707