2.7. Использование lambda-функций

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

Пример 2.21. lambda-функции

>>> def f(x): ... return x*2 ... >>> f(3) 6 >>> g = lambda x: x*2 1 >>> g(3) 6 >>> (lambda x: x*2)(3) 2 6
1 Эта lambda-функция делает то же самое, что и обычная функция, определенная выше. Обратите внимание на сокращенный синтаксис: список аргументов записывается без скобок и ключевое слово return отсутствует (оно подразумевается, так как тело функции может содержать только одно выражение). Кроме того, функция не имеет имени, но может быть вызвана через переменную, которой она присвоена.
2 Вы можете использовать lambda-функцию даже не присваивая ее переменной. Это не самый полезный пример, но он показывает, что lambda-функция может быть определена прямо в месте ее использования.

Обобщая, lambda-функция — это функция, которая имеет произвольное число аргументов (включая необязательные аргументы) и возвращает значение одного выражения. lambda-функции не могут содержать инструкций или более одного выражения. Не пытайтесь втискивать в lambda-функцию слишком много. Если вам необходимл что-либо более сложное — определите обычную функцию.

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

Пример 2.22. lambda-функции в apihelper.py

processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)

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

Во-вторых, мы используем метод split без аргументов. Вы уже видели его использование с одним и двумя аргументами, без аргументов метод split разбивает строку по символам пропуска (пробел, табуляция, возврат коретки, переход на новую строку).

Пример 2.23. split без аргументов

>>> s = "this is\na\ttest" 1 >>> print s this is a test >>> print s.split() 2 ['this', 'is', 'a', 'test'] >>> print " ".join(s.split()) 3 'this is a test'
1 Это строка, которая содержит символ переход на новую строку, записанный в виде специальной последовательности (такие строки могут быть также записаны с использованием утроенных кавычек). \n — переход на новую строку, \t — символ горизонтальной табуляции.
2 Метод split без аргументов разбивает строку по символам пропуска. В данном случае три пробела, переход на новую строку и табуляция воспринимаются одинаково.
3 Вы можете нормализовать пропуски разбив строку, а затем снова объединив ее, используя один пробул в качестве разделителя. Именно это делает функция help для того, чтобы свернуть строку документации.

Так что же на самом деле делает функция help с этими lambda-функциями, методами split и приемом с and-or?

Пример 2.24. Присваивание функции переменной

processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)

processFunc теперь ссылается на функцию, но на какую — это зависит от значения переменной collapse. Если collapse является истиной, processFunc(string) будет сворачивать символы пропуска, в противном случае processFunc(string) будет возвращать аргумент без изменений.

Для того, чтобы сделать это на менее мощном языке, например на Visual Basic, вы, скорее всего, будете использовать интсрукцию if, чтобы решить, сворачивать символы пропуска или нет. Такой подход неэффективен, так как проверять условие придется при каждом вызове функции. В языке Python вы можете принять решение один раз и определить lambda-функцию, которая будет делать только то, что вам нужно.

Дополнительная литература