Lambda в Python: шпаргалка для аналитика
Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.
Синтаксис
lambda arguments: expressionLambda — это анонимная функция из одного выражения. Эквивалент:
def f(x):
return x * 2
# ==
f = lambda x: x * 2Когда использовать lambda
- Короткая функция, которая нужна один раз
- Передать функцию как аргумент (map, filter, sorted, apply, groupby)
- Короткий key для сортировки / сравнения
Когда НЕ использовать: если функция длиннее одной строки или используется несколько раз — пишите def.
1. map()
nums = [1, 2, 3, 4]
squared = list(map(lambda x: x**2, nums))
# [1, 4, 9, 16]2. filter()
nums = [1, 2, 3, 4, 5, 6]
evens = list(filter(lambda x: x % 2 == 0, nums))
# [2, 4, 6]3. sorted() с ключом
users = [
{'name': 'Alice', 'age': 30},
{'name': 'Bob', 'age': 25},
]
sorted_users = sorted(users, key=lambda u: u['age'])
# сначала Bob, потом AliceОбратная сортировка:
sorted(users, key=lambda u: u['age'], reverse=True)Сортировка по нескольким ключам (кортеж):
sorted(users, key=lambda u: (u['age'], u['name']))4. max / min с ключом
products = [{'name': 'A', 'price': 100}, {'name': 'B', 'price': 200}]
most_expensive = max(products, key=lambda p: p['price'])
# {'name': 'B', 'price': 200}5. reduce()
from functools import reduce
nums = [1, 2, 3, 4, 5]
total = reduce(lambda a, b: a + b, nums)
# 156. pandas apply
import pandas as pd
df = pd.DataFrame({'price': [100, 200, 300], 'qty': [2, 3, 1]})
df['total'] = df.apply(lambda row: row['price'] * row['qty'], axis=1)На серии:
df['price_rub'] = df['price_usd'].apply(lambda x: x * 90)7. pandas groupby + agg / transform
# среднее отклонение от группы
df['diff_from_group'] = df.groupby('category')['value'].transform(
lambda x: x - x.mean()
)
# агрегация с lambda
df.groupby('category')['value'].agg(lambda x: x.quantile(0.95))8. Словарь с default-функцией (defaultdict)
from collections import defaultdict
d = defaultdict(lambda: 'неизвестно')
d['a'] = 'яблоко'
print(d['b']) # 'неизвестно'9. Sorting в classes
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
products = [Product('A', 100), Product('B', 50)]
sorted_products = sorted(products, key=lambda p: p.price)10. Условное выражение в lambda
Тернарный if:
classify = lambda x: 'big' if x > 100 else 'small'
classify(150) # 'big'
classify(50) # 'small'Несколько условий через цепочку:
grade = lambda x: 'A' if x >= 90 else 'B' if x >= 75 else 'C' if x >= 60 else 'F'(Но для такого лучше def с if/elif.)
Частые ошибки
Ошибка 1: lambda в цикле (closure issue)
# все функции в списке вернут 4 (последнее значение i)
funcs = [lambda: i for i in range(5)]
print([f() for f in funcs]) # [4, 4, 4, 4, 4]Правильно — захватить i:
funcs = [lambda i=i: i for i in range(5)]
print([f() for f in funcs]) # [0, 1, 2, 3, 4]Ошибка 2: Слишком длинная lambda
# плохо
lambda row: row['price'] * row['qty'] if row['status'] == 'paid' else 0 if row['refunded'] else row['price']
# хорошо — обычная функция
def total_amount(row):
if row['status'] == 'paid':
return row['price'] * row['qty']
elif row['refunded']:
return 0
return row['price']Ошибка 3: lambda для именованной логики
# плохо
is_premium = lambda user: user.subscription == 'premium'
# хорошо
def is_premium(user):
return user.subscription == 'premium'Ошибка 4: lambda вместо itemgetter / attrgetter
from operator import itemgetter, attrgetter
# работает, но медленнее
sorted(users, key=lambda u: u['age'])
# быстрее и яснее
sorted(users, key=itemgetter('age'))Производительность
- lambda не быстрее обычных функций (вызов то же самое)
- Для горячего кода:
itemgetter,attrgetter, list comprehensions часто быстрее - NumPy: vectorized операции >>> lambda в apply
Связанные темы
FAQ
Чем lambda отличается от обычной функции?
lambda — анонимная, только одно выражение, возвращает результат автоматически. def — именованная, может содержать много строк, явный return.
Можно ли в lambda использовать if/else?
Только тернарный: lambda x: a if condition else b. Обычный if на несколько строк — нельзя.
Почему lambda считают плохим стилем?
Не плохим, а неуместным в 70% случаев. В map/filter/sorted/apply — отлично. Как замена def — хуже читаемость.
Можно ли рекурсию в lambda?
Технически да через self = lambda x: ... self(x-1) ..., но практически — нет, используйте def.
Тренируйте Python для собесов — откройте тренажёр с 1500+ вопросами для аналитиков.