Python. Лямбда-вирази. Анонімні функції. Ключове слово lambda




Лямбда-вирази. Анонімні функції. Ключове слово lambda. Таблиця переходів


Зміст


Пошук на інших ресурсах:

1. Анонімні функції. Поняття. Ключове слово lambda. Загальна форма

Мова Python дозволяє задавати об’єкти функції у вигляді виразів. У цьому випадку ключове слово def замінюється ключовим словом lambda.

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

Загальна форма оголошення lambda-виразу наступна:

lambda agrument1, agrument2, ..., argumentN: expression

тут

  • argument1, argument2, argumentN – імена аргументів, які використовує lambda-вираз;
  • expression – безпосередньо лямбда-вираз.

Проаналізувавши загальну форму лямбда-виразу, можна прийти до таких висновків:

  • лямбда-вирази записуються в одному рядку. Якщо спробувати помістити вираз expression в інший рядок, то компілятор видасть помилку;
  • лямбда-вирази створюють функції, які не мають імені. Такі функції називаються анонімними функціями.

 

2. Випадки використання лямбда-виразів

Після того, як лямбда-вираз оголошено, він може бути використаний у таких випадках:

  • як функція. Це випадок, коли лямбда-вираз присвоюється деякому імені. Потім за цим іменем відбувається виклик лямбда-виразу;
  • як елемент (літерал) кортежу чи списку;
  • як елемент (літерал) словника, який за вимогою виконує деяку дію. У цьому випадку формується так звана таблиця переходів.

 

3. Відмінності між оголошенням та використанням лямбда-виразів (lambda) та функцій (def)

Між оголошенням та використанням лямбда-виразів та функцій існують наступні відмінності:

  • лямбда-вираз оголошується з допомогою ключового слова lambda, функція оголошується з допомогою ключового слова def;
  • лямбда-вирази – це вирази, def – це інструкції. Це означає, що лямбда-вираз може бути використаний там де не допускається використання def: всередині літералів чи викликах функцій;
  • лямбда-вираз містить тільки один вираз, який повертається. Результат обчислення виразу є результатом лямбда-виразу. Для повернення результату з лямбда-виразу не потрібно використовувати інструкцію return;
  • на відміну від оголошення функцій (def) лямбда-вирази призначені для обчислення більш простих фрагментів коду порівняно з функціями;
  • програмний код лямбда-виразу формується у вигляді одного рядка. Програмний код функції може містити довільну кількість рядків.

 

4. Переваги застосування лямбда-виразів

Використання лямбда-виразів дає наступні переваги:

  • лямбда-вирази зручні для створення функцій, що мають маленькі розміри;
  • лямбда-вирази спрощують програмний код, в який потрібно вбудовувати невеликі фрагменти;
  • програмний код може зручно використовувати лямбда-вирази замість визначення функцій там де потрібно;
  • лямбда-вирази забезпечують так звану близькість програмного коду. Анонімні інструкції розміщуються близько в програмі, що підвищує її читабельність та сприйняття і не потребує використання додаткових імен (як у випадку з функціями). Зменшення кількості імен в програмі знижує можливі конфлікти цих імен з іншими іменами у файлі модуля.

 

5. Приклади, що демонструють найпростіші лямбда-вирази. Відмінності між інструкціями def та lambda. Виклик лямбда-виразів як імен

У нижченаведених прикладах продемонстровано:

  • оголошення лямбда-виразу та його присвоєння деякому імені;
  • виклик (використання) лямбда-виразу за іменем;
  • відмінності між оголошенням та використанням функцій (def) та лямбда-виразів (lambda).

Приклад 1. Обчислення добутку трьох чисел.

# Лямбда-вирази і функції

# Обчислення добутку чисел.
# Лямбда-вираз, який повертає добуток трьох чисел
multL = lambda a, b, c: a * b * c # лямбда-вираз в одному рядку
resLambda = multL(2,5,5)         # виклик лямбда-виразу

# Функція, яка повертає добуток трьох чисел
def multF(a, b, c):
    return a*b*c

resFunc = multF(2,5,5) # виклик функції

# Вивід результату
print("resLambda = ", resLambda)
print("resFunc = ", resFunc)

Результат виконання програми

resLambda = 50
resFunc = 50

У вищенаведеному прикладі результат лямбда-виразу присвоюється імені multL

multL = lambda a, b, c: a * b * c

Потім виклик лямбда-виразу з конкретними значеннями (a = 2, b = 5, c = 5) присвоюється імені (об’єкту) resLambda

resLambda = multL(2,5,5) # виклик лямбда-виразу

У результаті, в об’єкті resLambda міститься добуток чисел 2*5*5 = 50.

Приклад 2. Лямбда-вираз, який повертає модуль комплексного числа.

# Лямбда-вирази і функції
import math

# 1. Лямбда-вираз, який визначає модуль комплексного числа
absL = lambda a, b: math.sqrt(a*a + b*b) # оголошення
resLambda = absL(3, 4) # виклик

# 2. Функція, яка повертає модуль комплексного числа
# Оголошення функції
def absF(a, b):
    return math.sqrt(a*a + b*b)

resFunc = absF(3,4) # виклик функції

# Вивід результату
print("resLambda = ", resLambda)
print("resFunc = ", resFunc)

Результат виконання програми

resLambda = 5.0
resFunc = 5.0

Приклад 3. Лямбда-вираз, який визначає дискримінант квадратного рівняння на основі коефіцієнтів a, b, c.

# Лямбда-вирази і функції

# 1. Лямбда-вираз, який обчислює дискримінант на основі коефіцієнтів a,b,c
discrL = lambda a, b, c: b*b - 4*a*c
print("discrLambda = ", discrL(3,4,5))

# 2. Функція, яка повертає дискримінант на основі коефіцієнтів a,b,c
# Оголошення функції
def discrF(a, b, c):
    return b*b-4*a*c

print("discrFunc = ", discrF(3,4,5))

Результат виконання програми

discrLambda = -44
discrFunc = -44

 

6. Приклади використання лямбда-виразів як літералів списків

Приклад 1. Використання лямбда-виразу як літералу списку.

На основі лямбда-виразів сформувати список випадкових чисел від 0 до 1.

# Лямбда-вирази як літерали списків

import random

# Словник, у якому формуються три випадкові числа
# з допомогою лямбда-виразу
L = [ lambda : random.random(),
      lambda : random.random(),
      lambda : random.random() ]

# Вивести результат
for l in L:
    print(l())

Результат виконання програми

0.5129490134837236
0.8638007610222296
0.915211196027481

Приклад 2. Формується кортеж, в якому елементи множаться на різні числа. Продемонстровано використання кортежу для рядка.

# Лямбда-вирази як літерали кортежів

import random

# Кортеж, у якому формуються три літерали-рядки
# з допомогою лямбда-виразу
T = ( lambda x: x*2,
    lambda x: x*3,
    lambda x: x*4 )

# Вивести результат для рядка 'abc'
for t in T:
    print(t('abc'))

Результат виконання програми

abcabc
abcabcabc
abcabcabcabc

 

7. Приклади використання лямбда-виразів для формування таблиць переходів у словниках

Приклад 1. Використання лямбда-виразу для формування таблиць переходів.

Сформувати таблицю переходів (словник), в якій за номером дня тижня виводиться його назву. Продемонструвати роботу створеної таблиці.

# Лямбда-вирази і таблиці переходів

# Словник, що є таблицею переходів
Dict = {
    1 : (lambda: print('Monday')),
    2 : (lambda: print('Tuesday')),
    3 : (lambda: print('Wednesday')),
    4 : (lambda: print('Thursday')),
    5 : (lambda: print('Friday')),
    6 : (lambda: print('Saturday')),
    7 : (lambda: print('Sunday'))
    }

# Викликати лямбда-вираз, що виводить назву вівторка
Dict[2]() # Tuesday

Приклад 2. Формується таблиця переходів (словник) Area, в якій обчислюється площа відомих фігур.

# Лямбда-вирази і таблиці переходів

import math

# Словник, що є таблицею переходів, в якій за назвою
# фігури виводиться її площа
Area = {
    'Circle' : (lambda r: math.pi*r*r), # коло
    'Rectangle' : (lambda a, b: a*b),   # прямокутник
    'Trapezoid' : (lambda a, b, h: (a+b)*h/2.0) # трапеція
    }

# Викликати лямбда-вираз, що виводить площу кола радіуса 2
print('Area of circle = ', Area['Circle'](2))

# Вивести площу прямокутника розміром 10*13
print('Area of rectangle = ', Area['Rectangle'](10, 13))

# Вивести площу трапеції для a=7, b=5, h=3
areaTrap = Area['Trapezoid'](7, 5, 3)
print('Area of trapezoid = ', areaTrap)

Результат виконання програми

Area of circle = 12.566370614359172
Area of rectangle = 130
Area of trapezoid = 18.0

 

8. Чи можна у лямбда-виразах використовувати оператори управління (if, for, while тощо)?

Відповідь: ні.

Згідно з синтаксисом лямбда-вираз розміщується в одному рядку. Якщо спробувати розмістити в одному рядку оператор while в тілі лямбда-виразу, то інтерпретатор Python видасть помилку “Invalid syntax” як показано нижче

# Тут видає помилку: "Invalid syntax"
lmbd = lambda n: while n>0: n=n-1
print("lmbd = ", lmbd)

Те саме стосується й інших керуючих конструкцій.

 


Зв’язані теми