Lambda: примеры (PYTHON)

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)); // 6
6

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); // 6
6

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)) // 6
6

Распространенные ошибки

Попытка использовать операторы или несколько выражений:

# Неверно
lambda x: print(x); x * 2  # Нельзя использовать оператор ;
# Верно - использование тернарного оператора для условия
lambda x: x * 2 if x > 0 else x
SyntaxError: 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 для последовательной агрегации:

Пример python
from functools import reduce
numbers = [1, 2, 3, 4]
product = reduce(lambda acc, val: acc * val, numbers, 1)
print(product)
24

Лямбда для динамического выбора атрибута объекта:

Пример python
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']

Эмуляция условного оператора в выражении для словаря:

Пример python
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

Лямбда внутри генератора словаря:

Пример python
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 для поиска по ключу:

Пример python
data = [{'val': 15}, {'val': -3}, {'val': 42}]
max_item = max(data, key=lambda d: d['val'])
print(max_item)
{'val': 42}

Лямбда для создания функции-замыкания с состоянием (с использованием изменяемого объекта):

Пример python
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

питон lambda function comments

En
Lambda Create anonymous function