lambda-функции в Python

Предупреждение
Последний раз данная статья обновлялась 11.05.2022, информация может быть устаревшей.

Список вопросов к Python собеседованию

В буквальном смысле, анонимная функция — это функция без имени. В Python анонимная функция создается с помощью ключевого слова lambda.1

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

1
lambda <args>: <expression>
Взаимозаменяемые термины

Следующие термины могут использоваться взаимозаменяемо в зависимости от языка программирования:

  • Анонимные функции
  • Лямбда-функции
  • Лямбда-выражения
  • Лямбда-абстракции
  • Лямбда-форма
  • Функциональные литералы

lambda поддерживают все способы передачи аргументов:

  • Позиционные аргументы;
  • Именованные аргументы;
  • Переменный список неименованных аргументов (*args);
  • Переменный список именованных аргументов (**kwargs).
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
(lambda x, y, z: x + y + z)(1, 2, 3)

(lambda x, y, z=3: x + y + z)(1, 2)

(lambda x, y, z=3: x + y + z)(1, y=2)

(lambda *args: sum(args))(1,2,3)

(lambda **kwargs: sum(kwargs.values()))(one=1, two=2, three=3)

(lambda x, *, y=0, z=0: x + y + z)(1, y=2, z=3)

Лямбда имеет синтаксические отличия от обычной функции:

  • Может содержать только выражение и не может включать операторы в свое тело;
  • Записывается в одну строку;
  • Не поддерживает аннотации типов;
  • Может быть немедленно вызвана (IIFE);
  • Не может содержать утверждения (return, pass, assert или raise вызовут исключение SyntaxError).

Декоратор может быть применен к лямбде. Хотя невозможно декорировать лямбду с помощью синтаксиса @decorator, декоратор — это просто функция, поэтому он может вызывать функцию lambda:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Defining a decorator
def trace(f):
    def wrap(*args, **kwargs):
        print(f"[TRACE] func: {f.__name__}, args: {args}, kwargs: {kwargs}")
            return f(*args, **kwargs)

        return wrap

# Applying decorator to a lambda
print((trace(lambda x: x ** 2))(3))

# [TRACE] func: <lambda>, args: (3,), kwargs: {}
  • Часто используются с функциями более высокого порядка, которые принимают одну или несколько функций в качестве аргументов или возвращают одну или несколько функций.
  • Может быть функцией более высокого порядка, принимая функцию (нормальную или лямбда-функцию) в качестве аргумента.
  • Регулярно используется со встроенными функциями map() и filter(), а также functools.reduce(), представленными в модуле functools.

Лямбда-функций следует избегать, когда код:

  • не следует руководству по стилю Python (PEP 8);
  • выглядит громоздким и трудно читаемым.

Всегда используйте оператор def вместо оператора присваивания, который связывает лямбду непосредственно с идентификатором. (PEP 8)2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# Сортировка списка
a = [(1, 2), (4, 1), (9, 10), (13, -3)]
a.sort(key=lambda x: x[1])

# Параллельная сортировка списков
data = list(zip(list1, list2))
data.sort()

# map
list(map(lambda x: x.upper(), ['cat', 'dog', 'cow']))
# ['CAT', 'DOG', 'COW']

# filter
list(filter(lambda x: 'o' in x, ['cat', 'dog', 'cow']))
# ['dog', 'cow']

# reduce
from functools import reduce

reduce(lambda acc, x: f'{acc} | {x}', ['cat', 'dog', 'cow'])
# 'cat | dog | cow'