ное выражение» в голове, пока его выполняете:
>>> (lambda x, y: x + y)(5, 3)
8
Ладно, и что же здесь произошло? Я просто использовал
lambda
, чтобы
определить однострочную функцию «
add
», а затем немедленно вызвал ее
с аргументами
5
и
3
.
Концептуально: лямбда-выражение
lambda
x,
y:
x
+
y
аналогично объяв-
лению функции при помощи ключевого слова
def
, только записывается
в одну строку. Основное отличие здесь в том, что перед его использова-
нием мне не пришлось связывать объект-функцию с именем. Я просто
сформулировал выражение, которое хотел вычислить как часть лямбды,
и затем немедленно его вычислил, вызвав лямбда-выражение как обыч-
ную функцию.
Прежде чем вы продолжите, возможно, вам стоит немного поэк-
спериментировать с приведенным выше примером кода, чтобы по-
настоящему усвоить его смысл. Я все еще помню, как не сразу до меня
это наконец дошло. Поэтому не переживайте по поводу того, что по-
тратите на него несколько минут в сеансе интерпретатора. Это будет
стоить того.
3 .2 . Лямбды — это функции одного выражения 77
Существует еще одно синтаксическое различие между определениями
лямбд и обычных функций. Лямбда-функции ограничены одним-един-
ственным выражением. Это означает, что в лямбда-функциях не могут
применяться инструкции или аннотации — и даже инструкция
return
.
Тогда каким образом возвращать значения из лямбд? При исполнении
лямбда-функции ее выражение вычисляется и затем результат выраже-
ния автоматически возвращается, поэтому всегда существует неявная
инструкция
return
. Именно поэтому некоторые разработчики называют
лямбды функциями одного выражения.
Лямбды в вашем распоряжении
В каких случаях в программном коде следует применять лямбда-функ-
ции? Технически вы можете применять лямбда-выражение в любой
ситуации, когда от вас ожидается, что вы предоставите объект-функцию.
И поскольку лямбды могут быть анонимными, перед этим вам даже не
нужно назначать им имя.
Этот факт обеспечивает удобную и «небюрократическую» краткую форму
для определения функции в Python. Мой самый частый вариант приме-
нения лямбд состоит в написании кратких и сжатых функций для сорти-
ровки итерируемых объектов по альтернативному ключу:
>>> tuples = [(1, 'd'), (2, 'b'), (4, 'a'), (3, 'c')]
>>> sorted(tuples, key=lambda x: x[1])
[(4, 'a'), (2, 'b'), (3, 'c'), (1, 'd')]
В приведенном выше примере мы сортируем список кортежей по второму
значению в каждом кортеже. В этом случае лямбда-функция обеспечивает
быстрый способ изменить порядок сортировки. Ниже приведен еще один
пример сортировки, с которым вы можете поиграть:
>>> sorted(range(-5, 6), key=lambda x: x * x)
[0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5]
Оба показанных мною примера имеют в Python более сжатые реализации
с использованием встроенных функций
operator.itemgetter()
и
abs()
.
78 Глава 3 • Эффективные функции
Но, надеюсь, вы заметили, как применение лямбды обеспечивает вам
гораздо большую гибкость. Хотите отсортировать последовательность
по некоему произвольно вычисленному ключу? Без проблем. Теперь вы
знаете, как это сделать.
Вот еще одна интересная вещь о лямбдах: как и обычные вложенные
функции, лямбды работают также и как лексические замыкания.
Что такое лексическое замыкание? Это лишь затейливое название для
функции, которая помнит значения из объемлющего лексического контек-
ста, даже когда поток управления программы больше не находится в этом
контексте. Вот (довольно академичный) пример, который иллюстрирует
эту идею:
>>> def make_adder(n):
... return lambda x: x + n
>>> plus_3 = make_adder(3)
>>> plus_5 = make_adder(5)
>>> plus_3(4)
7
>>> plus_5(4)
9
В приведенном выше примере лямбда
x
+
n
по-прежнему может получать
доступ к значению
n
, несмотря на то что она была определена в функции
make_adder
(объемлющем контексте).
Иногда применение лямбда-функции вместо вложенной функции, объ-
явленной при помощи ключевого слова
def
, может яснее выражать наме-
рение программиста. Но, честно говоря, это случается редко — по крайней
мере, не в том программном коде, который мне нравится писать. Поэтому
давайте поговорим об этом подробнее.
А может, не надо…
С одной стороны, я надеюсь, что эта глава заинтересовала вас исследова-
нием лямбда-функций Python. С другой стороны, я чувствую, что пора
озвучить еще одно предостережение: лямбда-функции следует применять
экономно и с необычайной осторожностью.
3 .2 . Лямбды — это функции одного выражения 79
Уж я-то знаю. Я написал изрядную долю исходного кода с использова-
нием лямбд, которые выглядели «круто», но на самом деле оказались по-
мехой для меня и моих коллег. Если вы испытываете желание применить
лямбда-функцию, потратьте несколько секунд (или минут) и обдумайте,
будет ли этот способ достижения нужного результата и вправду самым
чистым и максимально удобным в сопровождении.
Например, делать что-то подобное для экономии пары строк кода просто
глупо. Несомненно, технически все работает, и это вполне приличный
«трюк». Но он порядочно смутит очередную девчонку или парня, которые
в жесткие сроки должны отправить багфикс:
Do'stlaringiz bilan baham: |