Python поддерживает анонимные лямбда-функции с расширенной нотацией BNF.lambda_expr ::= "lambda" [parameter_list] ":" expression, это,lambda 参数序列:表达式.
Это удобный способ определения функций, в переводе на известную функциональную форму это будет выглядеть так:
def <lambda>(parameter_list):
return expression
Это,Лямбда-функция в Python — это функция, которая принимает несколько аргументов и возвращает выражение.
Его самым большим преимуществом является то, что он состоит из одной строки и не требует именования функций и отступа новой строки.
Я должен сказать, что анонимные функции иногда очень полезны, например, некоторые распространенные способы использования, которые будут представлены ниже, поэтому многие люди высоко ценят их.
Тем не менее, анонимные функции обычно также делают код трудным для чтения и легким для злоупотреблений, плюс Python предоставляет только «отключенную» поддержку для него, поэтому есть некоторые мнения, что использование анонимных функций не рекомендуется.
По факту,Гвидо ван Россум, отец Python, принадлежит к «устаревшей» фракции, однажды (2005) он даже хотел удалить лямбда-выражения, но в конце концов скомпрометировал.
Источник:Woohoo. Aretima.com/weblogs/VIE…
лямбда, фича, внесенная другими разработчиками (заимствованная из языка лисп), существует уже более десяти лет, но была презираема создателем (и главным дизайнером) языка и чудом сохранилась Сойди, как ты думаешь, эта история довольно драматично?
Далее в этой статье будет подробно рассказано об этой неуклюжей, но живучей анонимной лямбда-функции!
1. Как использовать лямбду?
Обычно лямбда-функции используются для объединения таких функций, как map(), reduce(), filter(), sorted() и т. д. Общими чертами этих функций являются:могут получать другие функции в качестве параметров.
Например, следующие примеры:
my_list = [3, 1, 5, 4, 10]
# 元素全加1,结果:[4, 2, 6, 5, 11]
list(map(lambda i:i+1, my_list))
# 过滤小于10的元素,结果:[3, 1, 5, 4]
list(filter(lambda i:i<10, my_list))
# 元素累加,结果:33
from functools import reduce
reduce(lambda i,j:i+j, my_list, 10)
# 字典按值排序,结果:[('b', 1), ('a', 3), ('d', 4), ('c', 5)]
my_dict = {'a':3, 'b':1, 'c':5, 'd':4}
sorted(my_dict.items(), key=lambda item:item[1])
Новичкам может показаться, что код непонятен, но просто запомните "Функции в Python — граждане первого класса», легко понять, зная, что функция может использоваться как параметр или возвращаемое значение другой функции.
Например, для примера функции map() вы можете понимать ее как эту форму:
my_func = lambda i:i+1
list(map(my_func, my_list))
Его даже можно вернуть к нормальной функции:
def add_one(i):
return i+1
list(map(add_one, my_list))
Первый параметр функции map() — это функция, а второй параметр — итерируемый объект. Первый параметр будет итеративно вызывать элементы во втором параметре, а результат вызова будет возвращен как итератор.
В этом примере используется list() для облегчения однократного извлечения элементов в итераторе и его интуитивного отображения.В реальном использовании он, вероятно, будет основан на итераторе.
Из этих применений мы можем обобщить правила использования лямбда-функций:
- Появляется там, где нужно использовать функцию
- Подходит для реализации простых функций
- Это одноразовое использование, и его нельзя использовать повторно в другом месте.
- Обычно не используется самостоятельно, всегда как часть других функций.
2. Что не так с лямбдой?
Как видно из приведенного выше использования, код, использующий лямбда-функцию, относительно компактен и лаконичен, поэтому некоторые люди говорят, что он воплощает элегантную идею «Pythonic».
Но есть ли недостатки у лямбда-функций?
имеют! Самая большая проблема с текущими лямбда-функциями заключается в том, что они поддерживают только однострочные выражения и не могут реализовывать расширенные функции.Например, они не могут использовать операторы при создании функций, не могут использовать условия оценки if-else и не могут использовать try-except. механизм и др.
Это сильно ограничивало его возможности, в результате чего его критиковали как «инвалида».
С технической точки зрения,Эта проблема может быть решена путем проектирования на уровне грамматики.
В групповом обсуждении в том же году некоторые люди предложили некоторые решения, такие как это электронное письмо:
Источник:Купил. Python.org/Piper mail/ Боюсь…
он представляет собойlambda args::suiteИдея поддержки записывается в такой форме:
ss = sorted(seq, key=(lambda x::
try: return abs(x)
except TypeError: return 0))
Однако Гвидо быстро отверг эту идею.
В ответ он написал статью «Дизайн языка — это не просто решение головоломок»:
Источник:Woohoo. Aretima.com/weblogs/VIE…
Его основной смысл:Вы не можете просто ввести языковой дизайн, в котором отсутствует «Pythonicity», просто для решения проблемы/реализации определенной функции.
Так почему же Гвидо считает это плохим дизайном?
Я пытаюсь обобщить, причина в следующем:
- Двойное двоеточие «::» введено здесь из ниоткуда, но оно полностью отличается от «::» в синтаксисе среза, а также отличается от использования оператора области видимости в C++/Perl.
- Даже без двойных двоеточий использование других символов (например, одинарных двоеточий) по-прежнему неприемлемо, поскольку в выражение встроены блоки кода с отступом. Это так же неприемлемо, как использование фигурных скобок и ключевых слов begin/end для группировки операторов.
- Реализация других функций в лямбде не важна, так же это усложнит парсер (нужно различать есть ли отступ, записывать уровень отступа), что перебор
короче,Он считает, что краткий и удобный пользовательский интерфейс важнее.Если краткий синтаксис не может удовлетворить потребности, его следует написать в виде именованной функции, а не разрабатывать сложную анонимную функцию.
3. Почему Гвидо хочет удалить лямбду?
Упомянутое выше лямбда-событие с несколькими операторами произошло в 2006 году, и мы понимаем, почему Гвидо не хочет вводить сложные конструкции в лямбда-выражения.
Однако еще в 2005 году Гвидо захотел убрать лямбда-выражения из Python, и его «отвращение» к ним стало «проверенной временем» традицией…
В короткой статье «Судьба редукции() в Python 3000» Гвидо предлагает удалить одновременно функции reduce(), map(), filter() и lambda.
Причины удаления лямбд следующие:
- Пользователей, незнакомых с Lisp или Scheme, может сбить с толку название lambda.
- Многие люди ошибочно думают, что анонимные функции могут делать то, чего не могут вложенные функции, но в этом нет никакой разницы; существование лямбда-выражений приведет к ненужному выбору, сократит выбор и упростит мышление.
- С удалением методов reduce(), map() и filter() нет необходимости писать короткие локальные функции.
Оглядываясь назад на четыре правила использования лямбда, которые мы обобщили в предыдущей статье, мы можем обнаружить, что у него есть сильные «паразитные отношения» с несколькими функциями более высокого порядка (функциями, которые могут получать другие функции в качестве параметров), если они могут быть удалено Если это так, лямбда действительно не имеет смысла сохраняться независимо.
Итак, почему Гвидо считает, что эти функции более высокого порядка должны быть удалены?
Основные причины:
- Может быть заменен более четким пониманием списка или выражениями генератора, например, фильтр (P, S) может быть записан как [x для x в S, если P (x)], map (F, S) как [F (x) для x в С]
- Что касается метода reduce(), он говорит, что это больше всего раздражает, за исключением нескольких применений, включающих + и *, в других случаях ему всегда приходится брать ручку и бумагу, чтобы нарисовать диаграмму, чтобы понять это. Помимо явного написания цикла, он предлагает несколько альтернатив для нескольких вариантов использования функции reduce(), включая введение новых функций any() и all().
В целом идея Гвидо перекликается с этой из «Дзен Python»:Должен быть один — и желательно только один — очевидный способ сделать это.
Но вернемся к реальности, чтобы позаботиться о привычках некоторых людей и соображениях совместимости, Гвидо, наконец, консервативно отказался от плана «очистить ересь».
Таким образом, лямбда смогла вырваться из рук верховного диктатора Питона. До тех пор, пока год спустя он не попытался создать волну (многострочные выражения), но был раздавлен.
Кажется, я слышу внутреннюю ОС Гвидо: когда я хотел что-то удалить, ты все заблокировал, теперь ты хочешь что-то добавить, а, ни за что! ...
Ха-ха, шучу.
Все решения Гвидо отражают эстетику его питонического дизайна, логическую последовательность и баланс мнений сообщества.
Я согласен с ним в отношении лямбда-выражений, и, оглядываясь назад на историю развития синтаксиса, я чувствую, что мое понимание Python стало намного богаче. Я не знаю, чувствуешь ли ты то же самое?
Наконец, несколько статей, связанных с программированием на Python, прилагаются в качестве расширенного чтения:
1,len(x) превосходит x.len(), рассматривая идеи дизайна Python из встроенных функций
2,Вопросы о языке программирования: когда заимствовать и когда создавать?
3.Почему Python сохраняет явное self?
4.Почему Python использует отступы для разделения блоков кода?