Многие языки программирования имеют понятие лямбда-функции. В Python лямбда-это анонимная функция или несвязанная функция. Синтаксис для них выглядит немного странно, но на самом деле он просто берет простую функцию и превращает ее в однострочник. Давайте посмотрим на обычную простую функцию для начала:
#----------------------------------------------------------------------
def doubler(number):
return x*2
Все, что делает эта функция — это взять целое число и удвоить его. Технически, это также удвоит другие вещи, так как нет проверки типов, но это его цель. Теперь давайте превратим это в лямбда-функцию!
К счастью, превратить однострочную функцию в лямбду довольно просто. Вот как:
doubler = lambda x: x*2
Таким образом, лямбда работает во многом так же, как и функция. Для ясности, «x» — это аргумент, который вы передаете. Двоеточие выделяет список аргументов из возвращаемого значения или выражения. Поэтому, когда вы добираетесь до части «x * 2», это то, что возвращается. Давайте посмотрим на другой пример:
>>> poww = lambda i: i**2
>>> poww(2)
4
>>> poww(4)
16
>>> (lambda i: i**2)(6)
36
Здесь мы покажем, как создать лямбду, которая принимает входные данные и возводит их в квадрат. В сообществе Python есть некоторые аргументы относительно того, следует ли вам назначать лямбда-переменную. Причина в том, что когда вы называете лямбду, она перестает быть анонимной, и вы можете просто написать обычную функцию. Весь смысл лямбды в том, чтобы использовать ее один раз и выбросить. Последний пример выше показывает один способ анонимного вызова лямбды (т.е. использовать его один раз).
Кроме того, если вы назовете лямбду, то вы можете просто сделать это:
>>> def poww(i): return i**2
>>> poww(2)
4
Давайте двигаться дальше и посмотрим, как использовать лямбду в понимании списка!
Лямбды, списки и карта
Мне всегда было трудно придумать хорошие способы использования лямбд, кроме как использовать их для обратных вызовов. Поэтому я пошел искать другие варианты использования. Кажется, что некоторые люди любят использовать их в списках. Вот пара примеров:
>>> [(lambda x: x*3)(i) for i in range(5)]
[0, 3, 6, 9, 12]
>>> tripler = lambda x: x*3
>>> [tripler(i) for i in range(5)]
[0, 3, 6, 9, 12]
Первый пример немного неловкий. Хотя он вызывает лямбда анонимно, его также немного трудно читать. В следующем примере лямбда-переменная присваивается переменной, а затем мы называем ее так. Самое смешное в этом то, что в Python есть встроенный способ вызова функции с итерируемым вызовом map . Вот как вы обычно используете это:
map(function, interable)
И вот реальный пример использования нашей лямбда-функции из более раннего:
>>> map(tripler, range(5))
[0, 3, 6, 9, 12]
Конечно, в большинстве случаев лямбда настолько проста, что сделать то же самое в понимании списка, вероятно, проще:
>>> [x*3 for x in range(5)]
[0, 3, 6, 9, 12]
Другие способы использования лямбды
Мои читатели предложили некоторые другие способы использования лямбды. Первый пример возвращает лямбду из вызова функции:
>>> def increment(n):
return lambda(x): x + n
>>> i = increment(5)
>>> i(2)
7
Здесь мы создаем функцию, которая будет увеличивать все, что мы даем ей, на 5. Один из моих других читателей предложил передать лямбду в сортированную функцию Python :
sorted(list, key=lambda i: i.address)
Идея здесь состоит в том, чтобы отсортировать список объектов с помощью свойства «адрес». Тем не менее, я по-прежнему считаю, что лучший вариант использования лямбды — это обратные вызовы событий, поэтому давайте посмотрим, как их использовать для этого с помощью Tkinter.
Использование лямбды для обратных вызовов
Tkinter — это инструментарий GUI, который поставляется с Python. Когда вы хотите взаимодействовать с вашим пользовательским интерфейсом, вы обычно используете клавиатуру и мышь. Эти взаимодействия работают через события, где и появляется лямбда. Давайте создадим простой пользовательский интерфейс, чтобы вы могли видеть, как лямбда используется в Tkinter!
import Tkinter as tk
########################################################################
class App:
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
frame = tk.Frame(parent)
frame.pack()
print_btn = tk.Button(frame, text='Print',
command=lambda: self.onPrint('Print'))
print_btn.pack(side=tk.LEFT)
close_btn = tk.Button(frame, text='close', command=frame.quit)
close_btn.pack(side=tk.LEFT)
#----------------------------------------------------------------------
def onPrint(self, num):
print "You just printed something"
#----------------------------------------------------------------------
if __name__ == "__main__":
root = tk.Tk()
app = App(root)
root.mainloop()
Итак, у нас есть простой пользовательский интерфейс с двумя кнопками. Одна кнопка вызывает метод onPrint с использованием лямбды, а другая использует метод Tkinter для закрытия приложения. Как видите, Tkinter использует лямбду так, как это было задумано. Лямбда здесь используется один раз, а затем выбрасывается. Нет ссылки на него, кроме как нажатием кнопки.
Завершение
Как, вероятно, знают мои давние читатели, я написал о лямбде в другой статье более пяти лет назад. В то время я не особо пользовался лямбдами и, честно говоря, до сих пор не пользуюсь. Они — отличная особенность языка, но после программирования на Python в течение более 9 лет я почти никогда не обнаруживал необходимости их использования, особенно в том смысле, как они предназначены для использования. Но каждому свое. Конечно, нет ничего плохого в использовании лямбд, но я надеюсь, что вы найдете эту статью полезной для выяснения, действительно ли вам нужно использовать их в своей работе.