Почему лямбда использования функционирует?

Я могу найти много материала, показывающего мне, что функция лямбды, и как синтаксис работает и что нет. Но кроме "фактора прохлады" (я могу сделать функцию в середине вызовом к другой функции, аккуратной!) Я не видел что-то, что это - overwelmingly, заставляющий для высказывания, почему я действительно должен использовать их.

Это, кажется, больше стилистического или структурного выбора в большинстве примеров, которые я видел. И вид повреждений "Только один корректный способ сделать что-то" в правиле Python. Как это делает мои программы, более корректные, более надежные, быстрее, или легче понять? (Большинство стандартов кодирования, которые я видел, имеет тенденцию говорить Вам избегать чрезмерно сложных операторов на одной строке. Если это помогает читать, разбивают его.)

64
задан skaffman 11 February 2012 в 15:29
поделиться

9 ответов

Вот хороший пример:

def key(x):
    return x[1]

a = [(1, 2), (3, 1), (5, 10), (11, -3)]
a.sort(key=key)

versus

a = [(1, 2), (3, 1), (5, 10), (11, -3)]
a.sort(key=lambda x: x[1])

С другой стороны: Лямбда-выражения также известны как "анонимные функции" и очень полезны в некоторых парадигмах программирования, особенно в функциональном программировании, вдохновением для которого послужило лямбда-исчисление.

http://en.wikipedia.org/wiki/Lambda_calculus

28
ответ дан 24 November 2019 в 15:58
поделиться

Лямбды позволяют создавать функции на лету. Большинство примеров, которые я видел, не делают ничего, кроме создания функции с параметрами, переданными во время создания, а не выполнения. Или они упрощают код, не требуя формального объявления функции перед использованием.

Более интересным использованием было бы динамическое построение функции python для оценки математического выражения, которое неизвестно до времени выполнения (ввод пользователя). После создания эту функцию можно многократно вызывать с разными аргументами для оценки выражения (скажем, вы хотите построить график). Это может быть даже плохой пример, учитывая eval (). В этом типе использования «реальная» сила - в динамическом создании более сложного кода, а не в простых примерах, которые вы часто видите, которые являются не более чем приятным (исходным) уменьшением размера кода.

-2
ответ дан 24 November 2019 в 15:58
поделиться

Одно из применений лямбда-функции, которое я узнал, и где нет другой хорошей альтернативы или, по крайней мере, выглядит для меня лучшим - это как действие по умолчанию в параметре функции by

parameter=lambda x: x

Это возвращает значение без изменений, но вы можете поставить одну функцию опционально, чтобы выполнить преобразование или действие (например, распечатать ответ, а не только вернуть)

Также часто полезно использовать в сортировке как ключ:

key=lambda x: x[field]

Эффект заключается в сортировке по полевому (нулевому, помните) элементу каждого элемента в последовательности. Для реверсирования вам не нужна лямбда, так как она более понятна в использовании

reverse=True

Часто почти так же просто сделать новую реальную функцию и использовать ее вместо лямбды. Если люди много изучали Лисп или другие функциональные программы, они также имеют естественную тенденцию использовать лямбда-функции, так как в Лиспе определения функций обрабатываются с помощью лямбда-исчисления.

2
ответ дан 24 November 2019 в 15:58
поделиться

Да, вы правы - это структурный выбор. Возможно, это не сделает ваши программы более правильными, если просто использовать лямбда-выражения. Это не делает их более надежными, и это не имеет ничего общего со скоростью.

Речь идет только о гибкости и силе выражения. Как понимание списка. Вы можете сделать большую часть этого определения именованных функций (возможно, загрязняя пространство имен, но это опять же чисто стилистическая проблема).

Это может улучшить удобочитаемость, потому что вам не нужно определять отдельную именованную функцию, что кто-то другой должен будет найти, прочитать и понять, что все, что он делает, это вызывает метод blah () для своего аргумента. .

Это может быть намного интереснее, когда вы используете его для написания функций, которые создают и возвращают другие функции, причем то, что именно делают эти функции, зависит от их аргументов. Это может быть очень краткий и понятный способ параметризации поведения вашего кода. Можно просто высказать больше интересных идей.

Но это все еще структурный выбор. Вы можете сделать это иначе. Но то же самое и с объектно-ориентированным программированием;)

6
ответ дан 24 November 2019 в 15:58
поделиться

Лямбда-функции наиболее полезны в таких вещах, как функции обратного вызова, или в местах, где вам нужна отбрасываемая функция. Пример JAB идеален - его лучше было бы сопровождать аргументом в виде ключевого слова key, но он все равно дает полезную информацию.

Когда

def key(x):
    return x[1]

появляется в 300 строках от

[(1,2), (3,1), (5,10), (11,-3)].sort(key)

что делает ключ? Здесь нет никаких указаний. Можно догадаться, особенно если вы знакомы с функцией, но обычно для этого приходится возвращаться назад, чтобы посмотреть. Напротив,

[(1,2), (3,1), (5,10), (11,-3)].sort(lambda x: x[1])

говорит вам гораздо больше.

  1. Sort принимает функцию в качестве аргумента
  2. Эта функция принимает 1 параметр (и "возвращает" результат)
  3. Я пытаюсь отсортировать этот список по 2-му значению каждого из элементов списка
  4. (Если бы список был переменной, так что вы не могли бы видеть значения), эта логика ожидает, что в списке должно быть по крайней мере 2 элемента.

Возможно, есть еще какая-то информация, но уже сейчас это огромное количество, которое вы получаете, просто используя анонимную лямбда-функцию вместо именованной функции.

Плюс она не загрязняет ваше пространство имен ;)

11
ответ дан 24 November 2019 в 15:58
поделиться

В некоторых случаях гораздо проще выразить что-то простое как лямбда. Рассмотрим, например, обычную сортировку и обратную сортировку:

some_list = [2, 1, 3]
print sorted(some_list)
print sorted(some_list, lambda a, b: -cmp(a, b))

В последнем случае написание отдельной полноценной функции только для возврата -cmp (a, b) создало бы больше недоразумений, чем лямбда.

0
ответ дан 24 November 2019 в 15:58
поделиться

Игнорируйте на мгновение деталь, о которой мы говорим именно анонимные функции .функции, в том числе анонимные, являются присваиваемыми величинами (почти, но не совсем значениями) в Python. в выражении вроде

map(lambda y: y * -1, range(0, 10))

явно упоминаются четыре анонимные величины: -1, 0, 10 и результат лямбда-оператора плюс подразумеваемый результат вызова map . в некоторых языках возможно создание значений анонимных типов . поэтому игнорируйте внешнюю разницу между функциями и числами. вопрос, когда использовать анонимную функцию, а не именованную, аналогичен вопросу о том, когда помещать в код литерал голого числа, а когда объявлять TIMES_I_WISHED_I_HAD_A_PONY или BUFFER_SIZE заранее. бывают случаи, когда уместно использовать литерал (числовой, строковый или функциональный), и бывают случаи, когда более уместно называть такую ​​вещь и ссылаться на нее через ее имя.

см., Например. Провокационная, заставляющая задуматься или вызывающая гнев книга Аллена Холуба о шаблонах проектирования на Java; он довольно часто использует анонимные классы.

5
ответ дан 24 November 2019 в 15:58
поделиться

Для меня это вопрос выразительности кода. Когда пишешь код, который придется поддерживать людям, этот код должен рассказывать историю в максимально сжатой и простой для понимания форме. Иногда лямбда-выражение сложнее, иногда оно более прямо говорит о том, что делает данная строка или блок кода. Используйте рассудительность при написании.

Думайте об этом как о структурировании предложения. Какие части важны (существительные и глаголы против объектов и методов и т.д.) и как они должны быть упорядочены, чтобы эта строка или блок кода передавали то, что они делают интуитивно.

9
ответ дан 24 November 2019 в 15:58
поделиться

Синтаксис более лаконичен в определенных ситуациях, в основном при работе с map et al.

map(lambda x: x * 2, [1,2,3,4])

кажется мне лучше, чем:

def double(x):
    return x * 2

map(double, [1,2,3,4])

Я думаю, что лямбда - лучший выбор в этой ситуации, потому что def double кажется почти не связанным с картой , которая его использует. Кроме того, я думаю, это имеет дополнительное преимущество в том, что функция выбрасывается, когда вы закончите.

На мой взгляд, у лямбда-выражений есть один недостаток, который ограничивает их полезность в Python: лямбда-выражения могут иметь только одно выражение (т. Е. У вас не может быть нескольких строк). Это просто не может работать на языке, который использует пробелы.

Кроме того, всякий раз, когда я использую лямбду, я чувствую себя прекрасно.

17
ответ дан 24 November 2019 в 15:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: