Что такое лямбда-функции в Python и каковы их особенности?
Что проверяют
Знаете ли вы ограничения лямбды и понимаете ли, когда она уместна, а когда мешает.
Как отвечать
Лямбда это анонимная функция, состоящая из одного выражения:
sorted(users, key=lambda u: u.age)Особенности:
- только выражение, никаких операторов. Присваивания,
ifкак оператора,for,tryвнутри быть не может. Тернарный оператор и генератор допустимы, потому что они выражения; - результат возвращается неявно,
returnне пишется; - это обычный объект функции, ничем не хуже созданного через
def, просто без имени. В трассировке она видна как<lambda>, что усложняет отладку; - можно присвоить переменной, но PEP 8 против: если функции нужно имя, объявляйте её через
def, это читаемее и даёт нормальное имя в ошибках; - замыкание работает как обычно, и отсюда классическая ловушка позднего связывания:
fns = [lambda: i for i in range(3)]
[f() for f in fns] # [2, 2, 2], а не [0, 1, 2]Переменная берётся в момент вызова, а не создания. Лечится значением по умолчанию: lambda i=i: i.
Где лямбда уместна: короткий ключ сортировки, простой предикат в filter, аргумент к min, max, groupby, значение по умолчанию у defaultdict.
Где лучше без неё: когда выражение перестало помещаться в строку, когда нужна документация или аннотации типов, и когда есть готовая замена. Для доступа к полю или элементу быстрее и понятнее operator.itemgetter и attrgetter, а вместо lambda x: x.method() часто подходит methodcaller.
Где спотыкаются
Пытаются написать внутри лямбды присваивание или несколько строк.
Присваивают лямбду имени вместо обычного объявления.
Попадают в ловушку позднего связывания в цикле.
Пишут filter(lambda x: x > 0, xs) там, где выражение-генератор читается лучше.