Учебники

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

Что такое лямбда?

Лямбды, также известные как анонимные функции, представляют собой небольшие ограниченные функции, которым не нужно имя (т. Е. Идентификатор). Лямбда-функции были впервые введены в область математики Алонзо Черчем в 1930-х годах.

Сегодня многие современные языки программирования, такие как Java, Python, C # и C ++, поддерживают лямбда-функции для добавления функциональности в языки.

В этом уроке по лямбде вы узнаете:

Лямбды в Python

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

Каждая анонимная функция, которую вы определяете в Python, будет состоять из 3 основных частей:

  • Лямбда ключевое слово.
  • Параметры (или связанные переменные) и
  • Тело функции.

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

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

Синтаксис и примеры

Формальный синтаксис для написания лямбда-функции приведен ниже:

lambda p1, p2: expression 

Здесь p1 и p2 — параметры, которые передаются лямбда-функции. Вы можете добавить столько параметров, сколько вам нужно.

Однако обратите внимание, что мы не используем скобки вокруг параметров, как с обычными функциями. Последняя часть (выражение) — это любое допустимое выражение Python, которое работает с параметрами, которые вы предоставляете функции.

Пример 1

Теперь, когда вы знаете о лямбдах, давайте попробуем это на примере. Итак, откройте свой IDLE и введите следующее:

adder = lambda x, y: x + y
print (adder (1, 2))

Вот вывод:

3

Код Объяснение

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

1. Ключевое слово lambda, используемое для определения анонимной функции.

2. x и y — параметры, которые мы передаем лямбда-функции.

3. Это тело функции, которое добавляет 2 параметра, которые мы передали. Обратите внимание, что это одно выражение. Вы не можете написать несколько операторов в теле лямбда-функции.

4. Вызываем функцию и печатаем возвращаемое значение.

Пример 2

Это был базовый пример для понимания основ и синтаксиса лямбды. Давайте теперь попробуем распечатать лямбду и посмотрим на результат. Снова откройте свой IDLE и введите следующее:

#What a lambda returns
string='some kind of a useless lambda'
print(lambda string : print(string))

Теперь сохраните ваш файл и нажмите F5, чтобы запустить программу. Это вывод, который вы должны получить.

Вывод:

<function <lambda> at 0x00000185C3BF81E0>

Что тут происходит? Давайте посмотрим на код, чтобы понять дальше.

Код Объяснение

  1. Здесь мы определяем строку, которую вы передадите в качестве параметра лямбде.
  2. Мы объявляем лямбду, которая вызывает оператор печати и печатает результат.

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

Пример 3

Однако, если вы напишите программу, подобную этой:

#What a lambda returns #2
x="some kind of a useless lambda"
(lambda x : print(x))(x)

И запустите его, нажав F5, и вы увидите такой вывод.

Вывод:

some kind of a useless lambda

Теперь вызывается лямбда, и передаваемая нами строка печатается на консоли. Но что это за странный синтаксис и почему лямбда-определение заключено в квадратные скобки? Давайте поймем это сейчас.

Код Объяснение

  1. Вот та же строка, которую мы определили в предыдущем примере.
  2. В этой части мы определяем лямбду и немедленно вызываем ее, передавая строку в качестве аргумента. Это то, что называется IIFE, и вы узнаете больше об этом в следующих разделах этого руководства.

Пример 4

Давайте посмотрим на последний пример, чтобы понять, как выполняются лямбда-выражения и обычные функции. Итак, откройте свой IDLE и в новом файле введите следующее:

#A REGULAR FUNCTION
def guru( funct, *args ):
funct( *args )
def printer_one( arg ):
return print (arg)
def printer_two( arg ):
print(arg)
#CALL A REGULAR FUNCTION 
guru( printer_one, 'printer 1 REGULAR CALL' )
guru( printer_two, 'printer 2 REGULAR CALL \n' )
#CALL A REGULAR FUNCTION THRU A LAMBDA
guru(lambda: printer_one('printer 1 LAMBDA CALL'))
guru(lambda: printer_two('printer 2 LAMBDA CALL'))

Теперь сохраните файл и нажмите F5, чтобы запустить программу. Если вы не допустили ошибок, вывод должен быть примерно таким.

Вывод:

принтер 1 обычный звонок

принтер 2 РЕГУЛЯРНЫЙ ВЫЗОВ

принтер 1 LAMBDA CALL

принтер 2 LAMBDA CALL

Код Объяснение

  1. Функция с именем guru, которая принимает другую функцию в качестве первого параметра и любые другие аргументы после него.
  2. printer_one — это простая функция, которая печатает переданный ей параметр и возвращает его.
  3. printer_two похож на printer_one, но без оператора return.
  4. В этой части мы вызываем функцию гуру и передаем функции принтера и строку в качестве параметров.
  5. Это синтаксис для достижения четвертого шага (то есть вызова функции гуру), но с использованием лямбд.

В следующем разделе вы узнаете, как использовать лямбда-функции с map (), redu () и filter () в Python.

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

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

IIFE в Python Lambda

IIFE обозначает выполнение немедленно вызванной функции. Это означает, что лямбда-функция вызывается, как только она определена. Давайте разберемся с этим на примере; запустите ваш IDLE и введите следующее:

 (lambda x: x + x)(2) 

Вот вывод и объяснение кода:

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

лямбды в фильтре ()

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

Элементы, которые будут выбраны, основаны на некотором предопределенном ограничении. Требуется 2 параметра:

  • Функция, которая определяет ограничение фильтрации
  • Последовательность (любой итератор, такой как списки, кортежи и т. Д.)

Например,

sequences = [10,2,8,7,5,4,3,11,0, 1]
filtered_result = filter (lambda x: x > 4, sequences) 
print(list(filtered_result))

Вот вывод:

[10, 8, 7, 5, 11]

Объяснение кода:

1. В первом утверждении мы определяем список, называемый последовательностями, который содержит несколько чисел.

2. Здесь мы объявляем переменную с именем Filter_result, которая будет хранить отфильтрованные значения, возвращаемые функцией filter ().

3. Лямбда-функция, которая запускается для каждого элемента списка и возвращает значение true, если оно больше 4.

4. Распечатайте результат, возвращаемый функцией фильтра.

лямбды на карте ()

функция map используется для применения определенной операции к каждому элементу в последовательности. Как и filter (), он также принимает 2 параметра:

  1. Функция, которая определяет операцию, чтобы выполнить на элементах
  2. Одна или несколько последовательностей

Например, вот программа, которая печатает квадраты чисел в данном списке:

sequences = [10,2,8,7,5,4,3,11,0, 1]
filtered_result = map (lambda x: x*x, sequences) 
print(list(filtered_result))

Вывод:

 [100, 4, 64, 49, 25, 16, 121, 0, 1]

[КР1]

Объяснение кода:

  1. Здесь мы определяем список, называемый последовательностями, который содержит несколько чисел.
  2. Мы объявляем переменную с именем Filter_result, которая будет хранить сопоставленные значения
  3. Лямбда-функция, которая запускается для каждого элемента списка и возвращает квадрат этого числа.
  4. Распечатать результат, возвращенный функцией карты.

лямбды в уменьшении ()

Функция Reduce, например map (), используется для применения операции к каждому элементу в последовательности. Тем не менее, он отличается от карты в своей работе. Далее следуют шаги, которые выполняет функция redu () для вычисления вывода:

Шаг 1) Выполните заданную операцию на первых 2 элементах последовательности.

Шаг 2) Сохраните этот результат

Шаг 3) Выполните операцию с сохраненным результатом и следующим элементом в последовательности.

Шаг 4) Повторяйте, пока не останется больше элементов.

Он также принимает два параметра:

  1. Функция, которая определяет операцию, которая будет выполнена
  2. Последовательность (любой итератор, такой как списки, кортежи и т. Д.)

Например, вот программа, которая возвращает произведение всех элементов в списке:

from functools import reduce
sequences = [1,2,3,4,5]
product = reduce (lambda x, y: x*y, sequences)
print(product)

Вот вывод:

120

Объяснение кода:

  1. Уменьшение импорта из модуля functools
  2. Здесь мы определяем список, называемый последовательностями, который содержит несколько чисел.
  3. Мы объявляем переменную с именем product, которая будет хранить уменьшенное значение
  4. Лямбда-функция, которая запускается для каждого элемента списка. Он вернет произведение этого числа согласно предыдущему результату.
  5. Распечатать результат, возвращаемый функцией Reduce.

Почему (и почему нет) использовать лямбда-функции?

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

Однако вы должны знать, когда стоит использовать лямбды и когда их избегать. В этом разделе вы узнаете некоторые принципы проектирования, используемые разработчиками Python при написании лямбд.

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

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

Когда не следует использовать лямбду?

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

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

Как уже говорилось ранее, лямбды — это [vV4] [J5] просто функции, с которыми не связан идентификатор. Проще говоря, это функции без имен (следовательно, анонимные). Вот таблица, чтобы проиллюстрировать разницу между лямбдами и обычными функциями в python.

Лямбда

Регулярные функции

Синтаксис:

lambda x : x + x 

Синтаксис:

def (x) :
return x + x 

Лямбда-функции могут иметь только одно выражение в своем теле.

Регулярные функции могут иметь несколько выражений и операторов в своем теле.

Лямбды не имеют имени, связанного с ними. Вот почему они также известны как анонимные функции.

Обычные функции должны иметь имя и подпись.

Лямбды не содержат оператора return, потому что тело возвращается автоматически.

Функции, которые должны возвращать значение, должны включать инструкцию возврата.

Объяснение различий?

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

Обычная функция для приведенного выше примера будет выглядеть так:

def adder (x, y):
return x + y 
print (adder (1, 2))

Здесь мы должны определить имя для функции, которая возвращает результат при его вызове . Лямбда-функция не содержит оператора return, потому что у нее будет только одно выражение, которое всегда возвращается по умолчанию. Вам даже не нужно назначать лямбду, так как она может быть немедленно вызвана (см. Следующий раздел). Как вы увидите в следующем примере, лямбды становятся особенно мощными, когда мы используем их со встроенными функциями Python.

Тем не менее, вы все еще можете задаться вопросом, чем лямбды отличаются от функции, которая возвращает единственное выражение (как показано выше). На уровне переводчика, нет большой разницы. Это может звучать удивительно, но любая лямбда-функция, которую вы определяете в Python, интерпретатор интерпретирует как нормальную функцию.

Как вы можете видеть на диаграмме, эти два определения обрабатываются интерпретатором Python одинаково при преобразовании в байт-код. Теперь вы не можете назвать лямбда- функцию, потому что она зарезервирована Python, но любое другое имя функции даст тот же байт-код [KR6].

Резюме

  • Лямбды, также известные как анонимные функции, представляют собой небольшие ограниченные функции, которым не нужно имя (т. Е. Идентификатор).
  • Каждая лямбда-функция в Python состоит из 3 основных частей:
  • Лямбда ключевое слово.
  • Параметры (или связанные переменные) и
  • Тело функции.
  • Синтаксис для написания лямбда-выражения: параметр лямбда-выражения: выражение
  • Лямбда может иметь любое количество параметров, но они не заключены в фигурные скобки
  • Лямбда может иметь только 1 выражение в теле функции, которое возвращается по умолчанию.
  • На уровне байт-кода нет большой разницы между тем, как интерпретатор обрабатывает лямбды и обычные функции.
  • Лямбды поддерживают IIFE через этот синтаксис: (лямбда-параметр: выражение) (аргумент)
  • Лямбды обычно используются со следующими встроенными модулями Python:
  • Фильтр: фильтр (лямбда-параметр: выражение, итеративная последовательность)
  • Карта: карта (лямбда-параметр: выражение, итеративные последовательности)
  • Уменьшить: уменьшить (лямбда-параметр1, параметр2: выражение, итеративная последовательность)
  • Не пишите сложные лямбда-функции в производственной среде, потому что это будет сложно для разработчиков кода.

[J5] Я добавил таблицу, но для понимания различий необходимо пояснение.

[vV4] Поместите этот раздел в таблицу fomat. Смотрите эту ссылку: https://www.guru99.com/call-by-value-vs-call-by-reference.html добавить дополнительные пункты в этом разделе.

[J3] Это ниже объяснения

[vV2] Изображение отсутствует в этом разделе.

[KR1] Не хотите, чтобы изображения кода… просто вставьте вывод в тег pre… делайте это везде

[KR6] Добавьте больше примеров, так как мы хотим, чтобы количество слов было 2300+