Что предпочтительнее использовать в Python: лямбда-функции или вложенные функции ('def')? - PullRequest
87 голосов
/ 25 сентября 2008

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

Вот несколько тривиальных примеров, когда они функционально делают то же самое, если они были найдены в другой функции:

Лямбда-функция

>>> a = lambda x : 1 + x
>>> a(5)
6

Вложенная функция

>>> def b(x): return 1 + x

>>> b(5)
6

Есть ли преимущества использования одного над другим? (Производительность? Читабельность? Ограничения? Согласованность? И т. Д.)

Это вообще имеет значение? Если это не так, это нарушает принцип Питона:

«Должен быть один - и желательно только один - очевидный способ сделать это» .

Ответы [ 16 ]

2 голосов
/ 26 июля 2018
  • Время вычислений.
  • Функция без имени.
  • Для достижения одной функции и многие используют функциональность.

Рассматривая простой пример,

# CREATE ONE FUNCTION AND USE IT TO PERFORM MANY OPERATIONS ON SAME TYPE OF DATA STRUCTURE.
def variousUse(a,b=lambda x:x[0]):
    return [b(i) for i in a]

dummyList = [(0,1,2,3),(4,5,6,7),(78,45,23,43)]
variousUse(dummyList)                           # extract first element
variousUse(dummyList,lambda x:[x[0],x[2],x[3]]) # extract specific indexed element
variousUse(dummyList,lambda x:x[0]+x[2])        # add specific elements
variousUse(dummyList,lambda x:x[0]*x[2])        # multiply specific elements
1 голос
/ 22 октября 2015

Я нашел одно использование для лямбд ... в сообщениях отладки.

Поскольку лямбды могут быть лениво оценены, у вас может быть такой код:

log.debug(lambda: "this is my message: %r" % (some_data,))

вместо, возможно, дорого:

log.debug("this is my message: %r" % (some_data,))

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

Конечно, чтобы он работал так, как описано, используемый модуль ведения журнала должен поддерживать лямбда-выражения как «ленивые параметры» (как это делает мой модуль ведения журнала).

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

Например, этот пользовательский троичный оператор:

def mif(condition, when_true, when_false):
    if condition:
         return when_true()
    else:
         return when_false()

mif(a < b, lambda: a + a, lambda: b + b)

вместо:

def mif(condition, when_true, when_false):
    if condition:
         return when_true
    else:
         return when_false

mif(a < b, a + a, b + b)

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

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

1 голос
/ 18 ноября 2008

Если вы просто собираетесь назначить лямбда-переменную в локальной области видимости, вы также можете использовать def, потому что она более читабельна и в будущем ее можно будет расширить:

fun = lambda a, b: a ** b # a pointless use of lambda
map(fun, someList)

или

def fun(a, b): return a ** b # more readable
map(fun, someList)
0 голосов
/ 18 октября 2017

Основное отличие состоит в том, что вы не можете использовать встроенные функции def, что, на мой взгляд, является наиболее удобным вариантом использования функции lambda. Например, при сортировке списка объектов:

my_list.sort(key=lambda o: o.x)

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

0 голосов
/ 25 апреля 2009

лямбда полезна для генерации новых функций:

def somefunc(x): return lambda y: x+y
f = somefunc(10)
f(2)
>>> 12
f(4)
>>> 14
0 голосов
/ 26 сентября 2008

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

E.G:

У вас есть функция с такой подписью: myFunction (data, callback function).

Вы хотите передать функцию, которая добавляет 2 элемента.

Использование лямбды:

myFunction(data, (lambda x, y : x + y))

Питонический путь:

import operator
myFunction(data, operator.add)

Или, конечно, это простой пример, но есть много вещей, которые предоставляет модуль оператора, включая установщики / получатели элементов для list и dict. Действительно круто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...