У цьому посібнику ви ознайомитеся з усіма аспектами лямбда-функцій у Python, починаючи від їхнього синтаксису і закінчуючи різноманітними прикладами застосування з демонстраційним кодом.
Лямбда-вирази в Python – це анонімні функції, що характеризуються лаконічним синтаксисом і можливістю їхнього використання спільно з іншими корисними вбудованими функціями. Після прочитання цього посібника, ви отримаєте чітке уявлення про те, як визначати лямбда-функції і коли їхнє застосування є доречним, на відміну від використання звичайних функцій Python.
Розпочнімо!
Лямбда-функції в Python: синтаксис та приклади
Ось стандартний синтаксис для оголошення лямбда-функції в Python:
lambda параметр(и): значення_що_повертається
З наведеного вище синтаксису стає зрозуміло, що:
lambda
– це ключове слово, яке використовується для визначення лямбда-функції, за яким слідує один або декілька параметрів, що приймаються функцією.- Двокрапка (
:
) відокремлює параметри від значення, яке повертається функцією.
💡 Створюючи лямбда-функцію, необхідно пам’ятати, що значення, яке повертається, має бути результатом обчислення виразу, який займає лише один рядок коду. Ви зрозумієте це краще, коли розглянемо приклади.
Демонстраційні приклади лямбда-функцій в Python
Найкращий спосіб зрозуміти лямбда-функції – почати з перетворення звичайних функцій Python на їх лямбда-еквіваленти.
👩🏽💻 Спробуйте програмувати разом зі мною в Python REPL або в онлайн-редакторі Python на techukraine.net.
#1. Розглянемо функцію square()
, яка приймає число num
і повертає його квадрат.
def square(num): return num*num
Можна викликати цю функцію з різними аргументами та перевірити, чи вона працює правильно.
>>> square(9) 81 >>> square(12) 144
Можна присвоїти лямбда-вираз змінній, наприклад, square1
, щоб зробити визначення функції більш коротким: square1 = lambda num: num*num
, а потім викликати square1
з будь-яким числом. Однак, оскільки лямбда-вирази є анонімними, краще уникати їхнього присвоєння змінним.
У функції square()
параметром є num
, а значенням, що повертається, є num*num
. Визначивши це, ми можемо перенести їх до лямбда-виразу і викликати його з аргументом:
>>> (lambda num: num*num)(2) 4
Це приклад негайно викликаної функції, коли функція виконується відразу після її оголошення.
#2. Далі розглянемо просту функцію add()
, яка приймає два числа (num1
та num2
) і повертає їхню суму.
def add(num1, num2): return num1 + num2
Викликаємо функцію add()
з двома числами як аргументи:
>>> add(4,3) 7 >>> add(12,5) 17 >>> add(12,6) 18
У цьому випадку num1
і num2
є параметрами, а значенням, що повертається, є num1 + num2
.
>>> (lambda num1, num2: num1 + num2)(3,7) 10
Функції Python можуть приймати значення за замовчуванням для параметрів. Змінимо функцію add()
, встановивши значення параметра num2
за замовчуванням на 10.
def add(num1, num2=10): return num1 + num2
У наступних викликах функції:
- У першому виклику значення
num1
дорівнює 1, аnum2
– 3. Коли ви передаєте значення дляnum2
, воно буде використане; функція поверне 4. - Якщо передати лише один аргумент (
num1
дорівнює 7), дляnum2
буде використано значення за замовчуванням 10; функція поверне 17.
>>> add(1,3) 4 >>> add(7) 17
Визначаючи функції, що використовують значення за замовчуванням для певних параметрів у вигляді лямбда-виразів, ви можете вказувати ці значення за замовчуванням під час оголошення параметрів.
>>> (lambda num1, num2 = 10: num1 + num2)(1) 11
Коли варто використовувати лямбда-функції в Python?
Ознайомившись з основами лямбда-функцій, розглянемо декілька ситуацій, коли їхнє застосування доречне:
- Якщо функція має однорядковий вираз, що повертає значення, і немає необхідності посилатися на неї в інших частинах модуля, то варто використовувати лямбда-функції. На прикладах вище ми це демонстрували.
- Лямбда-функції є корисними під час роботи з вбудованими функціями, такими як
map()
,filter()
таreduce()
. - Лямбда-функції можуть бути корисними при сортуванні структур даних, таких як списки та словники.
Застосування лямбда-функцій зі вбудованими функціями Python
1. Використання Lambda з map()
Функція map()
приймає ітерований об’єкт та функцію і застосовує цю функцію до кожного елемента ітерованого об’єкта:
Створимо список nums
і, використовуючи map()
, утворимо новий список, який міститиме квадрати кожного числа з nums
. Зверніть увагу на застосування лямбда-функції для визначення операції піднесення до квадрату.
>>> nums = [4,5,6,9] >>> list(map(lambda num:num*num,nums)) [16, 25, 36, 81]
Оскільки map()
повертає об’єкт-мапу, його потрібно перетворити на список.
▶️ Перегляньте докладний посібник про функцію map()
в Python.
2. Використання Lambda з filter()
Визначимо список чисел nums
:
>>> nums = [4,5,6,9]
Припустимо, необхідно відфільтрувати цей список, залишивши лише непарні числа.
Для цього можна скористатися вбудованою функцією filter()
.
Функція filter()
приймає умову та ітерований об’єкт: filter(condition, iterable)
. Результат містить лише ті елементи вихідного ітерованого об’єкта, які задовольняють умову. Можна перетворити об’єкт на ітерований об’єкт Python, наприклад, список.
Щоб відфільтрувати парні числа, залишивши лише непарні, лямбда-вираз має мати вигляд: lambda num: num%2 != 0
. num%2
– це залишок від ділення числа на 2.
num%2!=0
дорівнюєTrue
, колиnum
є непарним;num%2!=0
дорівнюєFalse
, колиnum
є парним.
>>> nums = [4,5,6,9] >>> list(filter(lambda num:num%2!=0,nums)) [5, 9]
3. Використання Lambda з reduce()
Функція reduce()
приймає ітерований об’єкт і функцію. Вона зменшує ітерований об’єкт шляхом багаторазового застосування функції до елементів.
Щоб скористатися функцією reduce()
, її необхідно імпортувати з модуля functools
:
>>> from functools import reduce
Використаємо функцію reduce()
для обчислення суми всіх чисел у списку nums
. Оголосимо лямбда-вираз: lambda num1, num2: num1 + num2
як функцію зменшення суми.
Операція згортання відбувається наступним чином: f(f(f(4,5),6),9) = f(f(9,6),9) = f(15,9) = 24
. Тут f
є операція підсумовування двох елементів, визначена лямбда-функцією.
>>> from functools import reduce >>> nums = [4,5,6,9] >>> reduce(lambda num1,num2:num1+num2,nums) 24
Лямбда-функції Python для налаштування сортування
Крім використання лямбда-функцій із вбудованими функціями map()
, filter()
та reduce()
, їх можна застосовувати для налаштування вбудованих методів сортування.
1. Сортування списків Python
Працюючи зі списками, часто виникає потреба сортувати їх за певним критерієм. Для сортування списків на місці застосовують метод sort()
. Якщо потрібна відсортована копія списку, використовуйте функцію sorted()
.
Синтаксис функції sorted()
: sorted(iterable, key=..., reverse=True | False)
.
- Параметр
key
використовується для визначення критерію сортування. - Параметр
reverse
приймає значенняTrue
абоFalse
; значенням за замовчуванням єFalse
.
При сортуванні чисел і рядків за замовчуванням відбувається сортування за зростанням та алфавітом. Але іноді є необхідність визначити власний критерій сортування.
Розглянемо приклад списку фруктів. Припустимо, потрібна відсортована копія списку, де рядки відсортовані за спаданням кількості входжень літери ‘p’.
>>> fruits = ['apple','pineapple','grapes','mango']
Тут застосуємо параметр key
. Рядок є ітерованим об’єктом, тому для отримання кількості входжень символу можна скористатися вбудованим методом .count()
. Встановлюємо key=lambda x: x.count('p')
, щоб сортування відбувалось за кількістю входжень ‘p’.
>>> fruits = ['apple','pineapple','grapes','mango'] >>> sorted(fruits,key=lambda x:x.count('p'),reverse=True) ['pineapple', 'apple', 'grapes', 'mango']
У цьому прикладі:
- Ключем сортування є кількість входжень ‘p’, що визначено лямбда-виразом.
- Оскільки
reverse=True
, сортування відбувається за спаданням кількості входжень ‘p’.
У списку fruits
рядок ‘pineapple’ містить три входження ‘p’, а рядки ‘apple’, ‘grapes’ і ‘mango’ містять 2, 1 і 0 входжень ‘p’ відповідно.
Розуміння стабільного сортування
Розглянемо інший приклад. Для того ж критерію сортування змінимо список фруктів. Тут ‘p’ з’являється в рядках ‘apple’ та ‘grapes’ два та один раз відповідно, і не з’являється в рядках ‘mango’ та ‘melon’.
>>> fruits = ['mango','apple','melon','grapes'] >>> sorted(fruits,key=lambda x:x.count('p'),reverse=True) ['apple', 'grapes', 'mango', 'melon']
У виведеному списку ‘mango’ йде перед ‘melon’, хоча в них відсутня ‘p’. Чому так? sorted()
виконує стабільне сортування, тобто порядок елементів зберігається, якщо критерій сортування однаковий для них.
Для закріплення, поміняйте місцями ‘mango’ і ‘melon’ у списку, відсортуйте за тим же критерієм і проаналізуйте результат.
▶️ Детальніше про сортування списків Python.
2. Сортування словника Python
Лямбда-вирази можна використовувати під час сортування словників. Розглянемо словник price_dict
, який містить товари та їхні ціни.
>>> price_dict = { ... 'Milk':10, ... 'Honey':15, ... 'Bread':7, ... 'Candy':3 ... }
Для представлення пар ключ-значення словника у вигляді списку кортежів, скористаємося методом .items()
:
>>> price_dict_items = price_dict.items() dict_items([('Milk', 10), ('Honey', 15), ('Bread', 7), ('Candy', 3)])
Усі ітеровані об’єкти: списки, кортежі, рядки мають нульову індексацію. Тобто перший елемент має індекс 0, другий – 1 і так далі.
Відсортуємо за значенням – ціною кожного елемента. В кожному кортежі price_dict_items
, елемент під індексом 1 є ціною. Встановлюємо key=lambda x:x[1]
, оскільки він буде використовувати елемент під індексом 1 (ціна) для сортування.
>>> dict(sorted(price_dict_items,key=lambda x:x[1])) {'Candy': 3, 'Bread': 7, 'Milk': 10, 'Honey': 15}
У результаті отримаємо словник, відсортований за зростанням ціни, починаючи з ‘Candy’ за ціною 3 і закінчуючи ‘Honey’ за ціною 15.
▶️ Детальний посібник про сортування словників Python за ключем і значенням.
Підсумок
Отже, ви навчилися визначати лямбда-функції та ефективно використовувати їх з іншими вбудованими функціями Python. Короткий підсумок:
- Лямбда-вирази – це анонімні функції, які можуть приймати декілька аргументів і повертати значення. Вираз, що обчислюється для отримання поверненого значення, має бути однорядковим. Їх можна використовувати для скорочення визначень невеликих функцій.
- Для визначення лямбда-функції використовується синтаксис:
lambda параметр(и): значення_що_повертається
. - Серед важливих сфер застосування – використання з
map()
,filter()
, таreduce()
, а також як параметрkey
для налаштування сортування.
Дізнайтеся більше про поділ поверхів у Python.