Функциональное программирование в Python

Анонимные функции: lambda

В общем виде lambda-выражение состоит из ключевого слова lambda, за которым следуют один или более аргументов (точно так же, как список аргументов в круглых скобках в заголовке инструкции def) и далее, вслед за двоеточием, находится выражение:

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

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

•• lambda – это выражение, а не инструкция. По этой причине ключевое сло-
во lambda может появляться там, где синтаксис языка Python не позволяет использовать инструкцию def, – внутри литералов или в вызовах функций, например. Кроме того, lambda-выражение возвращает значение (новую функцию), которое при желании можно присвоить переменной, в противовес инструкции def, которая всегда связывает функцию с именем в заголовке, а не возвращает ее в виде результата.
•• Тело lambda – это не блок инструкций, а единственное выражение. Тело lambda-выражения сродни тому, что вы помещаете в инструкцию return внутри определения def, – вы просто вводите результат в виде выражения вместо его явного возврата. Вследствие этого ограничения lambda-выражения менее универсальны, чем инструкция def – в теле lambda-выражения может быть реализована только логика, не использующая такие инструкции, как if. Такая реализация предусмотрена заранее – она ограничивает возможность создания большого числа уровней вложенности программ: lambdaвыражения предназначены для создания простых функций, а инструкции def – для решения более сложных задач.

Примеры lambda

> f = lambda x, y, z: x + y + z
>>> f(2, 3, 4)
9

 

> x = (lambda a=”fee”, b=”fie”, c=”foe”: a + b + c)
>>> x(“wee”)
‘weefiefoe’

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

 

> lower = (lambda x, y: x if x < y else y)
>>> lower(‘bb’, ‘aa’)
‘aa’

Функция map

 

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

>> counters = [1, 2, 3, 4]
>>>
>>> updated = []
>>> for x in counters:
… updated.append(x + 10) # Прибавить 10 к каждому элементу

>>> updated
[11, 12, 13, 14]

 

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

> def inc(x): return x + 10 # Функция, которая должна быть вызвана

>>> map(inc, counters) # Сбор результатов
[11, 12, 13, 14]

Или

>> list(map((lambda x: x + 3), counters)) # Выражение-функция
[4, 5, 6, 7]

Функция filter

Функция filter — отфильтровывают элементы с помощью функций выполняющих проверку (X>Y, X==Y, X<Y и т.д.)

Пример:

>> list(range(-5, 5)) # Итератор в Python 3.0
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
>>> filter((lambda x: x > 0), range(-5, 5)) # Итератор в Python 3.0
[1, 2, 3, 4]

Функция reduce

Функция reduce в Python 2.6 была простой встроенной функцией, но в версии 3.0 она была перемещена в модуль functools и стала более сложной. Она принимает итератор, но сама возвращает не итератор, а одиночный объект.
Ниже приводятся два вызова функции reduce, которые вычисляют сумму
и произведение элементов списка:

>> from functools import reduce # В 3.0 требуется выполнить импортирование
>>> reduce((lambda x, y: x + y), [1, 2, 3, 4])
10
>>> reduce((lambda x, y: x * y), [1, 2, 3, 4])
24