Базовый Python
October 31, 2022

Лямбда-функции в Python

Лямбда-функции в Python — это однострочные анонимные функции, которые отличаются от обычных своей компактностью, но имеют некоторые ограничения.

В этой статье мы разберём следующие нюансы:

Краткий экскурс в лямбда

Понятие лямбда существует не только в Python: оно также присутствует в Java, C#, C++ и других языках. Пришла же данная концепция ещё из математического исчисления.

Впервые вопрос лямбд был затронут ещё в 1930-х годах. В это время американский математик и логик Алонзо Чёрч формализовал лямбда-исчисление, благодаря чему получил широкую известность (тезис Чёрча — Тьюринга). Функциональные языки как раз основаны на математической логике и лямбда-исчислении, при этом ключевые языки программирования используют модель Алана Тьюринга. Модель Тьюринга и лямбда-исчисление можно перевести в одну расчётную модель, а суждение о данной эквивалентности и носит название тезиса Чёрча — Тьюринга.

Haskell, Lisp и прочие функциональные языки программирования делают акцент на лямбда-исчислении, в то время как Python, C и им подобные языки больше следуют императивному программированию.

Изначально Python не относился к числу функциональных языков, но впоследствии начал использовать некоторые функциональные концепции.

Что такое лямбда-функция

Лямбда-функции — это анонимные функции в Python. Они похожи на обычные функции, но за одним исключением: для определения им не требуются ни ключевое слово def, ни имя.

Для определения анонимных функций используется ключевое слово lambda

Если сравнить два способа определения функций, то можно выделить следующие моменты:

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

x = lambda x, y : x * y
print(x(3, 4))
# 12
x = (lambda x, y : x * y) (2, 3)
print(x)
# 6

На приведённых выше примерах мы видим лямбда-функцию, которая возвращает произведение переменных x и y. В первом случае x ссылается на саму функцию, а во втором же случае переменная x будет хранить в себе результат вызова этой анонимной функции.

Части лямбда-выражения:

  • Ключевое слово для создания — lambda.
  • Параметры — x и y.
  • Выражение — x * y.

Мы можем передать аргументы функции, поместив функцию и аргументы в круглые скобки:

x = (lambda x,y : x * y) (2, 3)
print(x)
# 6

При этом лямбда-функцию без проблем можно вызвать и без присваивания в переменную:

print((lambda x, y: x * y)(3, 5))
# 15

Как применять лямбда-функции

Давайте рассмотрим несколько примеров.

Для начала напишем код для вычисления показателя степени с помощью лямбда-функции:

exp = (lambda x, y : x ** y) (4, 4)
print(exp)
# 256

Теперь рассмотрим другой пример:

name = "Меня зовут Олег Булыгин"
lambda name: print(name)
# <function __main__.<lambda>(name)>

Проанализируем его:

  1. Была определена переменная name (это строка).
  2. Далее прописана лямбдa-функция, которая должна выводить результат.
  3. Но корректного результата мы не получаем.

Так происходит потому, что лямбда-функция является function-объектом, а в коде выше мы просто получаем область в памяти, где он расположен. Мы её здесь не вызываем, поэтому и не получаем результат исполнения функции.

Добавим вызов функции:

print((lambda name: print(name))(name))
# Меня зовут Олег Булыгин
# None

Теперь почти верно, но мы ещё видим лишний None после текста. В этом случае само выражение в лямбда-функции делает корректный вывод текста на экране, а внешний print выводит на экран то, что возвращает лямбда-функция (а она ничего не возвращает, в ней только print).

Попробуем исправить:

name = "Меня зовут Олег Булыгин"
print((lambda name: name)(name))
# Меня зовут Олег Булыгин

(lambda name: print(name))(name)
# Меня зовут Олег Булыгин

Теперь наш результат правильный, и даже двумя разными способами (с выводом на экран того, что функция возвращает и вызов print в самой лямбда-функции).

А как бы выглядел способ через определение обычной функции?

name = "Меня зовут Олег Булыгин"
def print_line(name):
    print(name)

print_line(name)
# Меня зовут Олег Булыгин

Какой способ вам кажется проще?

Когда стоит избегать использования лямбда-функций

Лямбда — это хорошо, но очень важно понимать, когда стоит избегать их использования.

Если вызов функции нам нужен многократно, то логично не использовать анонимную функцию, а создать функцию со своим именем, по которому мы её многократно будем вызывать в нужных местах программы.

Кроме того, если лямбда-функция приводит к тому, что страдает читаемость кода, то также стоит подумать о стандартном способе определения функций.

Альтернативы

Данные инструменты являются лучшей альтернативой лямбда-функциям, если задача состоит в том, чтобы создать список или словарь по определённому алгоритму. Но и о функциях высшего порядка, таких какmap(), reduce() и filter() также не стоит забывать, некоторые задачи с ними будут решаться не менее элегантно.

Источник: Medium

👉🏻Подписывайтесь на PythonTalk в Telegram 👈🏻

👨🏻‍💻Ещё больше полезного на OlegTalks💬

🍩 Поддержите канал 🫶