Lambda: примеры (PYTHON)
lambda(parameters: expression): functionЛямбда-функции в Python
Лямбда-функция в Python представляет собой анонимную функцию, объявляемую с помощью ключевого слова lambda. Она используется для создания небольших одноразовых функций, где определение стандартной функции через def было бы избыточным. Лямбда-функции часто применяют в качестве аргументов для функций высшего порядка, таких как map(), filter(), sorted().
Синтаксис и аргументы:
Основной синтаксис: lambda arguments: expression.
- arguments: список параметров, разделенных запятыми. Поддерживаются те же форматы, что и у обычных функций: позиционные аргументы, аргументы со значением по умолчанию (начиная с Python 3.12),
*argsдля переменного числа позиционных аргументов,**kwargsдля произвольного числа именованных аргументов. - expression: единственное выражение, результат вычисления которого автоматически возвращается функцией. Лямбда-функция не может содержать операторы (например,
ifбез тернарного оператора, циклы, присваивания) или аннотации типов. Тело функции ограничено одним выражением.
Возвращаемое значение:
Лямбда-функция возвращает объект-функцию. При вызове эта функция вычисляет и возвращает результат выражения expression. Тип возвращаемого значения определяется результатом вычисления выражения.
Базовые примеры использования
Пример с одним аргументом:
f = lambda x: x ** 2
print(f(5))25
Пример с несколькими аргументами:
mult = lambda a, b: a * b
print(mult(3, 4))12
Использование аргумента по умолчанию (Python 3.12+):
greet = lambda name, greeting='Hello': f'{greeting}, {name}'
print(greet('Anna'))
print(greet('Max', 'Hi'))Hello, Anna Hi, Max
Использование *args:
sum_all = lambda *args: sum(args)
print(sum_all(1, 2, 3, 4))10
Лямбда как ключ сортировки:
pairs = [(1, 'one'), (3, 'three'), (2, 'two')]
sorted_pairs = sorted(pairs, key=lambda item: item[0])
print(sorted_pairs)[(1, 'one'), (2, 'two'), (3, 'three')]
Альтернативы в Python
- Обычные функции (
def): Предпочтительны для любой логики, выходящей за рамки одного выражения, требующей операторов, аннотаций типов, декораторов или многоразового использования. Повышают читаемость. - Функции из модуля
operator: Для стандартных операций (operator.add,operator.itemgetter) часто являются более производительной и читаемой заменой простых лямбд. - Генераторы списков, словарей, множеств: Во многих случаях заменяют связку
map()/filter()с лямбдой, предлагая более питонический и зачастую понятный синтаксис. - Выражения-генераторы: Аналогичны генераторам списков, но для экономии памяти.
Аналоги в других языках
JavaScript (Стрелочные функции): Имеют более богатый синтаксис, могут содержать блок кода и неявно возвращают значение только при сокращенной форме. Контекст (this) привязан лексически.
const multiply = (a, b) => a * b;
console.log(multiply(2, 3)); // 66
Java (Лямбда-выражения): Могут использоваться только с функциональными интерфейсами (интерфейс с одним методом). Типы аргументов обычно выводятся.
BinaryOperator mult = (a, b) -> a * b;
System.out.println(mult.apply(2, 3)); // 6 6
PHP (Стрелочные функции): Имеют компактный синтаксис, автоматически захватывают переменные из родительской области видимости по значению. Тело - одно выражение.
$mult = fn($a, $b) => $a * $b;
echo $mult(2, 3); // 66
C# (Лямбда-оператор): Может быть как выражением, так и блоком операторов. Широко используется с делегатами и LINQ.
Func mult = (a, b) => a * b;
Console.WriteLine(mult(2, 3)); // 6 6
Kotlin (Лямбда-выражения): Синтаксис похож на Python, но если лямбда - последний аргумент функции, ее можно вынести за скобки.
val mult = { a: Int, b: Int -> a * b }
println(mult(2, 3)) // 66
Распространенные ошибки
Попытка использовать операторы или несколько выражений:
# Неверно
lambda x: print(x); x * 2 # Нельзя использовать оператор ;
# Верно - использование тернарного оператора для условия
lambda x: x * 2 if x > 0 else xSyntaxError: invalid syntax
Ошибки с захватом изменяющихся переменных из внешней области видимости:
funcs = []
for i in range(3):
funcs.append(lambda: i) # Все лямбды захватят ссылку на одну переменную i
print([f() for f in funcs]) # К моменту вызова i равно 2[2, 2, 2]
Исправление через аргумент по умолчанию:
funcs = []
for i in range(3):
funcs.append(lambda x=i: x) # Значение i фиксируется на момент создания
print([f() for f in funcs])[0, 1, 2]
Сложность чтения: Чрезмерно сложные лямбда-выражения ухудшают читаемость кода.
Изменения в последних версиях Python
В Python 3.12 в лямбда-функциях появилась возможность использовать аргументы со значениями по умолчанию, что раньше вызывало синтаксическую ошибку.
# Работает в Python 3.12+
f = lambda x, y=10: x + y
print(f(5))
print(f(5, 20))15 25
Раньше для этого требовались обходные пути, например, использование functools.partial.
Расширенные примеры применения
Использование с functools.reduce для последовательной агрегации:
from functools import reduce
numbers = [1, 2, 3, 4]
product = reduce(lambda acc, val: acc * val, numbers, 1)
print(product)24
Лямбда для динамического выбора атрибута объекта:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
people = [Person('Alice', 30), Person('Bob', 25)]
# Сортировка по возрасту
sorted_by_age = sorted(people, key=lambda p: p.age)
print([p.name for p in sorted_by_age])['Bob', 'Alice']
Эмуляция условного оператора в выражении для словаря:
config = {'mode': 'debug'}
get_value = lambda key, default: config.get(key) if config.get(key) is not None else default
print(get_value('mode', 'production'))
print(get_value('port', 8080))debug 8080
Лямбда внутри генератора словаря:
operations = {
'add': lambda a, b: a + b,
'subtract': lambda a, b: a - b
}
print(operations['add'](10, 5))
print(operations['subtract'](10, 5))15 5
Использование с max/min для поиска по ключу:
data = [{'val': 15}, {'val': -3}, {'val': 42}]
max_item = max(data, key=lambda d: d['val'])
print(max_item){'val': 42}Лямбда для создания функции-замыкания с состоянием (с использованием изменяемого объекта):
def make_counter():
count = [0] # Используем список для изменяемого состояния
return lambda: (count.__setitem__(0, count[0] + 1), count[0])[1]
counter = make_counter()
print(counter(), counter(), counter())1 2 3