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

Список чисел sorted() отсортирует сама: с числами всё понятно — меньше, больше. А вот со списком студентов уже вопрос: что сравнивать — имена, оценки? Python этого не знает.

Чтобы подсказать, sorted() принимает маленькую вспомогательную функцию: та берёт одного студента и возвращает значение, по которому сравнивать, — например оценку. Заводить ради одной такой строки полноценную функцию через def, придумывать ей имя и выносить отдельным блоком — громоздко.

Для таких случаев есть лямбда-функции: крошечная функция прямо там, где она нужна, без имени и без def.

Python 3.13
lambda аргументы: выражение

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

Сравним обычную функцию и лямбду, которые делают одно и то же:

Python 3.13
def square(x):
    return x * x

square_lambda = lambda x: x * x

print(square(5))
25
print(square_lambda(5))
25

Запись короче: имени нет, return не пишется — возвращается результат единственного выражения. Правда, сохранять лямбду в переменную, как здесь, почти не приходится: её сила — в передаче напрямую туда, где нужна маленькая функция. Начнём с задачи из вступления.

sorted(): сортировка по своему правилу

У sorted() есть параметр key — функция, которая достаёт из элемента значение для сравнения. Лямбда пишется прямо в вызове:

Python 3.13
students = [
    {"name": "Alice", "grade": 85},
    {"name": "Bob", "grade": 92},
    {"name": "Charlie", "grade": 78},
]

sorted_by_grade = sorted(students, key=lambda student: student["grade"], reverse=True)
for student in sorted_by_grade:
    print(f"{student['name']}: {student['grade']}")
Bob: 92
Alice: 85
Charlie: 78

key=lambda student: student["grade"] — та самая вспомогательная функция из вступления: берёт студента, возвращает его оценку. А reverse=True разворачивает порядок от большей к меньшей. Правило сравнения может быть любым — например, отсортируем числа по абсолютному значению:

Python 3.13
numbers = [5, -3, 2, -8, 1, 0, -2]

print(sorted(numbers, key=lambda x: abs(x)))
[0, 1, 2, -2, -3, 5, -8]

map(): применить функцию к каждому элементу

map() применяет функцию к каждому элементу списка, а list(...) собирает результаты в новый список:

Python 3.13
numbers = [1, 2, 3, 4, 5]

doubled = list(map(lambda x: x * 2, numbers))
print(doubled)
[2, 4, 6, 8, 10]
celsius = [0, 10, 20, 30]
fahrenheit = list(map(lambda c: c * 9 / 5 + 32, celsius))
print(fahrenheit)
[32.0, 50.0, 68.0, 86.0]

filter(): отобрать элементы по условию

filter() оставляет только те элементы, для которых функция вернула True:

Python 3.13
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

even = list(filter(lambda x: x % 2 == 0, numbers))
print(even)
[2, 4, 6, 8, 10]
words = ["hi", "hello", "hey", "howdy"]
long_words = list(filter(lambda word: len(word) > 3, words))
print(long_words)
['hello', 'howdy']

Когда лямбда, а когда def

Лямбда уместна, когда функция простая — одно выражение — и нужна один раз, обычно как аргумент sorted(), map() или filter().

Ограничения вытекают из самой записи:

  • тело — ровно одно выражение: ни нескольких строк, ни присваиваний внутри;
  • имени нет, поэтому вызвать её из другого места не получится.

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

Проверка понимания

Какое из следующих утверждений о лямбда-функциях в Python верно?

В следующем уроке — обработка ошибок: что делать, когда программа падает, и как try/except превращает аварию в управляемую ситуацию.