21 ноября 2012 г.

Функция lambda


Анонимная функция lambda

Помимо def есть lambda, c их помощью можно создавать объекты функций.

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

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

Основы lambda - выражений:
lambda argument1, argument2,... argumentN : выражение, использующее аргументы

Различия lambda от def:
 lambda – это выражение, а не инструкция. По этой причине ключевое слово lambda  может  появляться там, где синтаксис  языка  Python не позволяет использовать инструкцию def, – внутри литералов или в вызовах функций, например.

   • Тело  lambda – это не блок инструкций, а единственное выражение.  Тело
lambda-выражения сродни тому, что вы помещаете в инструкцию return внутри определения def, – вы просто вводите результат в виде выражения вместо  его явного  возврата.


Посмотрим различия на примере кода:
Без выражения lambda:
>>> def func(x, y, z): return x + y + z
...
>>> func(2, 3, 4)
9

С выражением lambda:
>>> f = lambda x, y, z: x + y + z
>>> f(2, 3, 4)
9
-----------------------------------------------------------------


Использование значений по умолчанию в lambda-выражениях:
>>> x = (lambda a=”fee”, b=”fie”, c=”foe”: a + b + c)
>>> x(“wee”)
‘weefiefoe’
-----------------------------------------------------------------

Те же самые правила поиска переменных в областях видимости, что и для вложенных инструкций def:
lambda-выражения 
создают локальную область видимости, как и вложенные инструкции def, и ав
томатически получают доступ к именам в объемлющих функциях, в модуле 
и во встроенной области видимости (в соответствии с правилом LEGB).
>>> def knights():
...     title = ‘Sir’
...     action = (lambda x: title + ‘ ‘ + x) # Заголовок в объемлющей def
...     return action                        # Возвращает функцию
...
>>> act = knights()
>>> act(‘robin’)
‘Sir robin’
-----------------------------------------------------------------

Когда можно использовать lambda-выражения:
 - Для создания таблиц переходов, 
которые представляют собой списки или словари действий, выполняемых по 
требованию. 
Например:
L = [lambda x: x**2,   # Встроенные определения функций
     lambda x: x**3, 
     lambda x: x**4]   # Список из трех функций

for f in L:
    print(f(2))        # Выведет 4, 8, 16

print(L[0](3))         # Выведет 9

Тот же пример без использования lambda:
def f1(x): return x ** 2
def f2(x): return x ** 3   # Определения именованных функций
def f3(x): return x ** 4

L = [f1, f2, f3]           # Ссылка по имени

for f in L:
    print(f(2))            # Выведет 4, 8, 16

print(L[0](3))             # Выведет 9
-----------------------------------------------------------------


Подобные таблицы действий в языке Python можно создавать с помощью словарей и других структур данных. 
Пример, выполненный в интерактивном сеансе:
>>> key = ‘got’
>>> {‘already’: (lambda: 2 + 2),
...  ‘got’:     (lambda: 2 * 4),
...  ‘one’:     (lambda: 2 ** 6)}[key]()
8

Тот же пример без использования lambda:
>>> def f1(): return 2 + 2
...
>>> def f2(): return 2 * 4
...
>>> def f3(): return 2 ** 6
...
>>> key = ‘one’
>>> {‘already’: f1, ‘got’: f2, ‘one’: f3}[key]()
64
-----------------------------------------------------------------

Так же возможна реализация логики выбора внутри lambda-функций:
>>> lower = (lambda x, y: x if x < y else y)
>>> lower(‘bb’, ‘aa’)
‘aa’
>>> lower(‘aa’, ‘bb’)
‘aa’
-----------------------------------------------------------------

Если необходимо выполнить цикл внутри lambda, то можно использовать map и генераторы списков:
Пример №1
>>> import sys
>>> showall = lambda x: list(map(sys.stdout.write, x)) 
                                    # Функция list 
                                    # необходима в 3.0 
>>> t = showall([‘spam\n’, ‘toast\n’, ‘eggs\n’])
spam
toast
eggs

Пример №2 
>>> showall = lambda x: [sys.stdout.write(line) for line in x] 
>>> t = showall((‘bright\n’, ‘side\n’, ‘of\n’, ‘life\n’))
bright
side
of
life
-----------------------------------------------------------------

Вложенные lambda-выражения и области видимости:
Соблюдается правило LEGB.
Например, lambda-выражение находится внутри  инструкции  def – типичный  случай – и  потому  получает 
значение имени x из области видимости объемлющей функции, имевшееся на 

момент ее вызова:
>>> def action(x):
...     return (lambda y: x + y) # Создать и вернуть ф-цию, 
...                              # запомнить x
>>> act = action(99)
>>> act
<function <lambda> at 0x00A16A88>
>>> act(2)         # Вызвать функцию, созданную ф-цией action
101

Предыдущая инструкция def в виде lambda-выражения:
>>> action = (lambda x: (lambda y: x + y))
>>> act = action(99)
>>> act(3)
102
>>> ((lambda x: (lambda y: x + y))(99))(4)
103
Эта  структура  lambda-выражений  создает функцию,  которая при  вызове создает  другую функциюВ обоих случаях вложенное  lambda-выражение имеет доступ к переменной x в объемлющем lambda-выражении.

2 комментария:

  1. Теперь все понял, можно еще добавить как тут https://pythonstart.ru/osnovy/anonimnaya-funktsiya-lambda-python

    ОтветитьУдалить