Лямбда-функции в Python
Лямбда-функция — это маленькая анонимная функция, которая может принимать любое количество аргументов, но содержит только одно выражение.
В переводе с программистского на человеческий:
- Анонимная — у неё нет имени (в отличие от обычных функций, определяемых через def)
- Маленькая — она ограничена одним выражением (одной строкой кода)
- Функция — она принимает аргументы и возвращает результат
Синтаксис лямбда-функции
lambda аргументы: выражение
Где:
- lambda — это ключевое слово, которое сообщает Python, что мы создаём лямбда-функцию
- аргументы — это входные параметры (могут быть от 0 до нескольких, разделенных запятыми)
- выражение — это одно выражение, результат которого будет возвращен
Сравнение с обычными функциями
Давайте сравним обычную функцию и лямбда-функцию, которые делают одно и то же:
# Обычная функция >>> def square(x): ... return x * x # Эквивалентная лямбда-функция >>> square_lambda = lambda x: x * x # Используем обе функции >>> print(square(5))
25>>> print(square_lambda(5))25# Функция с несколькими аргументами >>> def power(base, exponent): ... return base ** exponent # Эквивалентная лямбда-функция >>> power_lambda = lambda base, exponent: base ** exponent >>> print(power(2, 3))8>>> print(power_lambda(2, 3))8
Как видите, лямбда-функции более компактны, но менее читаемы для сложных операций.
Когда использовать лямбда-функции?
Лямбда-функции лучше всего подходят для случаев, когда:
- Функция простая (одно выражение)
- Функция используется только один раз (или несколько раз в одном месте)
- Функция передается как аргумент другой функции
Наиболее распространенные случаи использования — с функциями высшего порядка, такими как map(), filter(), sorted() и др.
Лямбда с функциями высшего порядка
map() — применение функции к каждому элементу
Функция map() применяет указанную функцию к каждому элементу итерируемого объекта:
# Удвоение всех чисел в списке >>> numbers = [1, 2, 3, 4, 5] # С обычной функцией >>> def double(x): ... return x * 2 >>> doubled = list(map(double, numbers)) >>> print(doubled)
[2, 4, 6, 8, 10]# С лямбда-функцией (гораздо компактнее!) >>> doubled_lambda = list(map(lambda x: x * 2, numbers)) >>> print(doubled_lambda)[2, 4, 6, 8, 10]# Преобразование температуры из Цельсия в Фаренгейт >>> celsius = [0, 10, 20, 30, 40] >>> fahrenheit = list(map(lambda c: (c * 9/5) + 32, celsius)) >>> print(fahrenheit)[32.0, 50.0, 68.0, 86.0, 104.0]
filter() — отбор элементов по условию
Функция filter() создает итератор из элементов, для которых функция возвращает True:
# Фильтрация четных чисел >>> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # С лямбда-функцией >>> even_lambda = list(filter(lambda x: x % 2 == 0, numbers)) >>> print(even_lambda)
[2, 4, 6, 8, 10]# Фильтрация слов длиннее 3 букв >>> words = ["hi", "hello", "hey", "howdy", "hi there"] >>> long_words = list(filter(lambda word: len(word) > 3, words)) >>> print(long_words)['hello', 'howdy', 'hi there']
sorted() — сортировка с пользовательским ключом
Функция sorted() возвращает отсортированный список, а с помощью параметра key можно указать функцию для извлечения значения для сравнения:
# Сортировка чисел по абсолютному значению >>> numbers = [5, -3, 2, -8, 1, 0, -2] >>> sorted_numbers = sorted(numbers, key=lambda x: abs(x)) >>> print(sorted_numbers)
[0, 1, 2, -2, -3, 5, -8]# Сортировка словарей по значению определенного ключа >>> students = [ ... {"name": "Alice", "grade": 85}, ... {"name": "Bob", "grade": 92}, ... {"name": "Charlie", "grade": 78}, ... {"name": "Diana", "grade": 95} ... ] # Сортировка по оценке (по убыванию) >>> sorted_by_grade = sorted(students, key=lambda student: student["grade"], reverse=True) >>> for student in sorted_by_grade: ... print(f"{student['name']}: {student['grade']}")Diana: 95Bob: 92Alice: 85Charlie: 78
reduce() — последовательное применение функции
Функция reduce() (из модуля functools) последовательно применяет функцию к элементам, накапливая результат:
>>> from functools import reduce # Сумма всех чисел в списке >>> numbers = [1, 2, 3, 4, 5] >>> total_lambda = reduce(lambda x, y: x + y, numbers) >>> print(total_lambda)
15# Объединение строк >>> words = ["Hello", "world", "of", "Python"] >>> sentence = reduce(lambda x, y: x + " " + y, words) >>> print(sentence)Hello world of Python
Передача лямбда-функций в другие функции
Лямбда-функции часто используются как аргументы в других функциях:
>>> def apply_operation(x, y, operation): ... """Применяет операцию к двум числам и возвращает результат""" ... return operation(x, y) # Использование с разными лямбда-функциями >>> print(apply_operation(5, 3, lambda x, y: x + y)) # Сложение
8>>> print(apply_operation(5, 3, lambda x, y: x * y)) # Умножение15# Форматирование данных >>> def format_data(data, formatter): ... """Форматирует данные с помощью указанной функции""" ... return [formatter(item) for item in data] >>> names = ["alice", "bob", "charlie"] >>> print(format_data(names, lambda x: x.title())) # Начало с заглавной['Alice', 'Bob', 'Charlie']
Ограничения лямбда-функций
Лямбда-функции имеют несколько важных ограничений:
- Только одно выражение — нельзя использовать несколько строк кода
- Отсутствие документации — нельзя добавить docstring
- Ограниченная читаемость — для сложных операций лучше обычные функции
- Нет оператора присваивания — в лямбде нельзя использовать =
# Пример сложной логики, где лучше не использовать лямбду >>> complex_lambda = lambda x: ( ... x ** 2 if x > 0 ... else x + 1 if x < 0 ... else 42 ... ) ... print(complex_lambda(5))
25# То же самое, но с обычной функцией - гораздо понятнее >>> def process_number(x): ... """Обрабатывает число по правилам: ... - Положительное -> квадрат ... - Отрицательное -> x + 1 ... - Ноль -> 42 ... """ ... if x > 0: ... return x ** 2 ... elif x < 0: ... return x + 1 ... else: ... return 42 >>> print(process_number(5)) 25
Проверка понимания
Какое из следующих утверждений о лямбда-функциях в Python верно?