- Принцип работы именованных функций
- Принцип работы анонимных функций
- Особенности анонимных функций
- Выводы
Представим, что нам нужно написать функцию для выполнения определенного действия, но создание отдельной функции кажется излишним. Чтобы решить эту проблему, можно использовать анонимные функции. Они позволяют определить функцию «на лету» внутри другой функции или выражения.
В этом уроке мы изучим, что такое анонимные функции, как их определять и использовать в Python. Также рассмотрим примеры, где использование анонимных функций может значительно упростить написание кода. Но для начала вспомним, что такое именованные функции.
Принцип работы именованных функций
Именованные функции в Python — это функции, которым назначено имя с помощью оператора def
. Он позволяет создавать функции, которые можно вызывать по имени из любой точки программы.
Пример именованной функции:
def add_numbers(x, y):
return x + y
Здесь именованная функция — add_numbers
. Она принимает два аргумента x
и y
и возвращает их сумму.
Еще бывают ситуации, когда нужна функция, чтобы ее передать, например, в функцию высшего порядка. Но больше эта функция нигде не понадобится.
Придумывание имен в программировании — одна из основных проблем. Но если функция нужна здесь и сейчас, и больше нигде ее вызывать не придется, то и имя ей не нужно. Такие одноразовые функции называются анонимными или лямбда-функциями.
Принцип работы анонимных функций
Анонимные функции — это функции, у которых нет имени. Они определяются с помощью ключевого слова lambda
. Это ключевое слово названо в честь лямбда-абстракции — основы Лямбда Исчисления. Это математический аппарат, который часто применяется в разработке языков программирования. В Лямбда Исчислении все функции — анонимные. Поэтому анонимные функции во многих языках тоже иногда называют лямбдами или лямбда-функциями.
Такие функции обычно используются в качестве аргументов функций высшего порядка, таких как map()
, filter()
и reduce()
. Также они позволяют описывать практически все языки, которые умеют работать с функциями как со значениями.
В Python определение подобной функции выглядит так:
lambda x: x + 1
# <function <lambda> at 0x7f56e5798a60>
Мы сконструировали функцию, но имя она не получила, поэтому REPL ее отобразил как function <lambda>
.
Рассмотрим пример, который использует анонимную функцию:
l = [1, 2, 5, 3, 4]
l.sort(key=lambda x: -x)
l
# [5, 4, 3, 2, 1]
Метод sort
принимает в качестве аргумента key
ссылку на функцию. В примере в качестве аргумента указана функция, которая меняет знак у аргумента. По этой причине список получается отсортирован от большего к меньшему.
Сортировка с указанием ключа встречается довольно часто, а вот ключи сортировки чаще всего будут разными. Поэтому выносить ключи в именованные функции смысла нет и анонимные функции здесь подходят.
Рассмотрим другой пример, который использует анонимную функцию вместе с функцией map()
:
l = [1, 2, 3, 4, 5]
result = list(map(lambda x: x * 2, l))
result
# [2, 4, 6, 8, 10]
В данном примере функция map()
принимает анонимную функцию и список данных. Анонимная функция lambda x: x * 2
принимает один аргумент x
и умножает его на два. Функция map()
применяет эту анонимную функцию к каждому элементу списка l
и возвращает новый список, в котором каждый элемент удвоен. Результат сохраняется в переменной result
и выводится на экран.
Теперь рассмотрим пример работы с функцией filter
:
l = [1, 2, 3, 4, 5]
result = list(filter(lambda x: x % 2 == 0, l))
result
# [2, 4]
Этот код использует функцию filter
. Она фильтрует элементы входной последовательности, согласно условию, которое задано в лямбда-функции. В нашем примере функция фильтрует элементы списка l
.
Здесь лямбда-функция lambda x: x % 2 == 0
определяет, что элемент должен быть четным — его остаток при делении на два должен быть равен нулю.
Функция filter
применяет лямбда-функцию к каждому элементу списка l
и оставляет только те элементы, для которых лямбда-функция возвращает True
. Затем эти элементы используются для создания нового списка с помощью функции list
.
Посмотрим на еще один пример применения анонимной функции, но уже с функцией reduce
:
from functools import reduce
l = [1, 2, 3, 4, 5]
result = reduce(lambda x, y: x * y, l)
result
# 120
В данном примере используется лямбда-функция, которая принимает два аргумента: x
и y
. В итоге она возвращает их произведение. Итерируемый объект l
содержит числа [1, 2, 3, 4, 5]
. Поэтому функция reduce
последовательно умножает каждую пару чисел в списке: (1 * 2) * 3) * 4) * 5
. Это приводит к результату 120
.
Особенности анонимных функций
Рассмотрим главные особенности анонимных функций:
- Аргументы анонимных функций не заключены в скобки. К этому нужно будет привыкнуть. Остальные средства для описания аргументов доступны в полной мере — и именованные аргументы, и
*args
с**kwargs
- Тело лямбда-функции — это всегда одно выражение, результат вычисления которого и будет возвращаемым значением. В теле лямбда-функции не получится выполнить несколько действий и не получится использовать многострочные конструкции вроде
for
иwhile
. Но зато анонимные функции обычно просто читать, чего было бы сложно добиться, разреши авторам "многострочные" лямбды - Объявление функции является выражением. Функции можно конструировать и тут же вызывать, не заканчивая выражение:
1 + (lambda x: x * 5)(8) + 1
# 42
В таком виде лямбды встречаются редко. Зато часто можно встретить возврат лямбды из функции:
def caller(arg):
return lambda f: f(arg)
call_with_five = caller(5)
call_with_five(str)
# '5'
call_with_five(lambda x: x + 1)
# 6
Из этого примера можно понять, что лямбды являются замыканиями — возвращаемая лямбда запоминает значение переменной arg
.
Выводы
В этом уроке мы познакомились с принципами работы анонимных функций, узнали, зачем они нужны, а также разобрали их особенности. Анонимные функции полезны для создания коротких функций, которые нужны только для конкретной задачи и не используются в других местах кода. Это удобно, когда нужно написать простую функцию, которую не нужно определять отдельно, или когда функция не нужна в других местах программы.
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.