Иногда возникает необходимость написать небольшую функцию, которая будет использоваться один раз, да и то в сочетании с какими-нибудь другими функциями или методами. В таком случае совсем необязательно создавать эту функцию с помощью def
и присваивать ей имя. Можно воспользоваться специальными lambda-функциями, которые создаются в одну строчку и могут существовать без имени (их ещё назвают анонимными).
Для начала создадим какую-нибудь не-анонимную функцию, чтобы познакомиться с синтаксисом. Пусть это будет функция sq
, которая принимает на вход какое-то число x
и возвращает его квадрат.
sq = lambda x: x ** 2 # готово
Использовать эту функцию можно как функции, заданные через def
:
sq(10)
100
sq(-7)
49
Если функция принимает на вход более одного аргумента, они просто перечисляются через запятую после lambda
:
my_sum = lambda x, y: x + y
my_sum(0, 7)
7
my_sum(6, 7)
13
Теперь посмотрим на сочетание lambda-функций с встроенными функциями Python. Lambda-функции часто используют в сочетании с функциями filter()
и map()
, которые позволяют отфильтровывать значения списков/кортежей или преобразовывать их элементы (более быстрая и удобная альтернатива списковым включениям).
Если вы помните, когда мы обсуждали списки, мы говорили про метод .index()
, который возвращает индекс какого-то элемента по его значению. Проблема в том, что в случае списка с повторяющимися значениями он возвращает только первое совпадение:
L = [0, 2, 7, 5, 4, 3, 2]
L.index(2) # только первая 2
1
Если мы захотим таким образом вернуть все элементы, удовлетворяющие некоторому условию, ничего не получится (понадобятся циклы, условия, списковые включения). А можно просто написать lambda-функцию, которая будет возвращать значения True или False в зависимости от соответствия условию, а потом передать полученный результат функции filter()
, которая отберет элементы с True:
list(filter(lambda x: x > 3, L)) # элементы списка L больше 3
[7, 5, 4]
list(filter(lambda x: x % 2 == 0, L)) # четные элементы списка L
[0, 2, 4, 2]
Условия можно совмещать:
list(filter(lambda x: (x > 3) & (x < 7), L)) # 3 < x < 7
[5, 4]
Обратите внимание: перед filter()
всегда добавляется list()
. Это нужно для того, чтобы увидеть результаты явно и получить их в виде списка. Иначе мы просто получим «закрытый» объект типа filter()
( вспомните историю про zip()
).
filter(lambda x: x > 3, L)
<filter at 0x10dde1eb8>
Теперь попробуем совместить lambda-функцию и функцию map()
, которая позволяет получать новый список на основе старого, преобразовывая его элементы:
list(map(lambda x: x ** 2, L)) # квадраты элементов списка L
[0, 4, 49, 25, 16, 9, 4]