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

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

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

Ответ 1

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

def key(x):
    return x[1]

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

против

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

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

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

Ответ 2

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

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

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

def double(x):
    return x * 2

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

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

Существует один недостаток лямбда, который ограничивает его полезность в Python, на мой взгляд: lambdas может иметь только одно выражение (т.е. вы не можете иметь несколько строк). Он просто не может работать на языке, который создает пробелы.

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

Ответ 3

Лямбда-функции наиболее полезны в таких вещах, как функции обратного вызова или места, в которых вам нужна функция throwaway. Пример 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 параметр (и "возвращает" результат)
  • Я пытаюсь отсортировать этот список по 2-ому значению каждого из элементов списка
  • (Если список был переменной, поэтому вы не могли видеть значения), эта логика ожидает, что в списке будет как минимум 2 элемента.

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

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

Ответ 4

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

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

Ответ 5

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

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

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

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

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

Ответ 6

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

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

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

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

Ответ 7

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

parameter=lambda x: x

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

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

key=lambda x: x[field]

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

reverse=True

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

Ответ 8

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

Прямо от PEP8

"Один из ключевых соображений Guido - это то, что код читается гораздо чаще, чем он написан".

Ответ 9

Lambdas - это объекты, а не методы, и они не могут быть вызваны таким же образом, как и методы. например,

succ = ->(x){ x+1 }

succ mow содержит объект Proc, который мы можем использовать как любой другой:

succ.call(2)

дает нам выход = 3

Ответ 10

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

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

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

Ответ 11

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

from tkinter import *
from tkinter import ttk        
def callback(arg):
    print(arg)
    pass
root = Tk()
ttk.Button(root, text = 'Button1', command = lambda: callback('Button 1 clicked')).pack()
root.mainloop()

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

ttk.Button(root, text = 'Button1', command = callback('Button1 clicked')).pack()

Ответ 12

Другое дело, что у python нет операторов switch. Объединение лямбда с диктонами может быть эффективной альтернативой. например:.

switch = {
 '1': lambda x: x+1, 
 '2': lambda x: x+2,
 '3': lambda x: x+3
}

x = starting_val
ans = expression
new_ans = switch[ans](x)

Ответ 13

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

Ответ 14

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

def power(n):
    return lambda x: x**n

square = power(2)
cubic = power(3)
quadruple = power(4)

print(square(10)) # 100
print(cubic(10)) # 1000
print(quadruple(10)) # 10000

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

Ответ 15

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

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