Lambda-функции
Lambda-функции
Мы уже умеем передавать функции как аргументы — например, map(square, numbers). Иногда функция нужна только один раз, и создавать её через def ради единственного использования — избыточно. Для таких случаев Python предоставляет лямбда-функции: анонимные функции в одну строку.
Синтаксис lambda
lambda параметры: выражение
Лямбда — это выражение, которое создаёт функцию. Она не имеет имени (отсюда «анонимная») и всегда возвращает результат единственного выражения:
square = lambda x: x ** 2
print(square(5)) # 25
add = lambda a, b: a + b
print(add(3, 4)) # 7
Эти две записи эквивалентны:
# Обычная функция:
def double(x):
return x * 2
# Лямбда:
double = lambda x: x * 2
Если вы пишете f = lambda ..., лучше использовать def — это читаемее. Настоящая сила лямбды — передача прямо в вызов функции без именования.
Лямбды в sorted(), min(), max()
Самое частое применение — аргумент key= для сортировки:
words = ["яблоко", "груша", "абрикос", "слива"]
# Сортировка по длине слова:
print(sorted(words, key=lambda w: len(w)))
# ['слива', 'груша', 'яблоко', 'абрикос']
# Сортировка по последнему символу:
print(sorted(words, key=lambda w: w[-1]))
Без лямбды пришлось бы определять отдельную функцию. С лямбдой критерий виден прямо в строке сортировки.
Пример со списком словарей:
students = [
{"name": "Алиса", "grade": 92},
{"name": "Борис", "grade": 78},
{"name": "Вера", "grade": 85},
]
# Сортировка по оценке (убывание):
top = sorted(students, key=lambda s: s["grade"], reverse=True)
for s in top:
print(f"{s['name']}: {s['grade']}")
# Алиса: 92
# Вера: 85
# Борис: 78
Лямбды в map() и filter()
map(func, iterable) применяет функцию к каждому элементу. filter(func, iterable) оставляет только те, для которых функция вернула True:
numbers = [1, 2, 3, 4, 5, 6]
squares = list(map(lambda x: x ** 2, numbers))
print(squares) # [1, 4, 9, 16, 25, 36]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4, 6]
Те же результаты можно получить через list comprehensions — и зачастую это читаемее:
squares = [x ** 2 for x in numbers]
evens = [x for x in numbers if x % 2 == 0]
Лямбды vs list comprehensions — вопрос стиля. Для sorted(key=...) и min/max(key=...) лямбды компактнее. Для map/filter — list comprehensions обычно предпочтительнее.
Ограничения lambda
Лямбда может содержать только одно выражение — не несколько операторов, не if/else в полном виде:
# Тернарный if/else в лямбде — допустимо:
classify = lambda x: "чётное" if x % 2 == 0 else "нечётное"
print(classify(4)) # чётное
print(classify(7)) # нечётное
# Несколько строк — нельзя, нужна обычная функция:
# lambda x: y = x * 2; return y # SyntaxError
Если логика сложнее одного выражения — используйте def. Лямбда — инструмент краткости, не замена функциям.
Проверь себя
Что выведет следующий код?
pairs = [(1, 3), (2, 1), (4, 2)]
pairs.sort(key=lambda p: p[1])
print(pairs)
Сортировка по второму элементу каждого кортежа: 3 → 1 → 2 стало бы 1 → 2 → 3. Вывод: [(2, 1), (4, 2), (1, 3)].
Итог
lambda параметры: выражение— анонимная функция в одну строку.- Возвращает результат выражения (без явного
return). - Лучший сценарий:
key=дляsorted(),min(),max(). - Для
map()иfilter()обычно предпочтительнее list comprehensions. - Лямбда не поддерживает несколько операторов — для сложной логики используйте
def.
В следующем уроке изучим docstrings и аннотации типов — как документировать функции так, чтобы IDE и коллеги понимали что они принимают и возвращают.