Функціональне програмування

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

Елементи функціонального програмування в Python можуть бути корисні будь-якому програмісту, бо дозволяють гармонійно поєднувати виразну потужність цього підходу з іншими підходами. Як правило, коли говорять про елементи функціонального програмування в Python, то розглядають такі функції вищого порядку:

  • lambda 
  • map 
  • filter 
  • zip

Анонімні функції
Крім звичайних функцій мова Python дозволяє використовувати анонімні функції, які називаються лямбда-функціями. Анонімна функція описується за допомогою ключового слова lambda за наступною схемою:

lambda[<Параметр 1>[..., <Параметр N>]]: <Значення, що повертається>

Після ключового слова lambda можна вказати параметри, що передаються. У якості параметра <Значення, що повертається> вказується вираз, результат виконання якого буде повернутий функцією. Як видно зі схеми, у лямбда-функцій немає імені. З цієї причини їх і називають анонімними функціями.

У якості значення лямбда-функція повертає посилання на об'єкт-функцію, яку можна зберегти у змінній або передати в якості параметра у іншу функцію. Викликати лямбда-функцію можна, як і звичайну, за допомогою круглих дужок, усередині яких розташовані передані параметри. Приклад використання лямбда-функцій:


Як і в звичайних функціях, деякі параметри лямбда-функцій можуть бути необов'язковими. Для цього параметрам у визначенні функції присвоюється значення за замовчуванням:








Найчастіше не зберігають посилання у змінній, а відразу передають як параметр в іншу функцію. Наприклад, метод списків sort() дозволяє вказати функцію користувача в параметрі key. Відсортуємо список спочатку з урахуванням регістру, а потім без урахування регістру символів, вказавши в якості параметра лямбда-функцію:











Функція map
Вбудована функція map() дозволяє застосувати певну функцію до кожного елементу послідовності. Функція має наступний формат:

map(<Функція>, <Послідовність 1> [..., <Послідовність N>])

Функція map() повертає об’єкт, що підтримує ітерації, а не список, як це було раніше в Python 2. Щоб отримати список у версії Python 3, необхідно результат передати в функцію list().
У якості параметру <Функція> вказується посилання на функцію (назва функції без круглих дужок), якій буде передаватися поточний елемент послідовності. Усередині функції зворотного виклику необхідно повернути нове значення.
Піднесемо до квадрату кожний елемент списку:

Результат виконання:
[1, 4, 9, 16, 25, 36, 49]

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









У цьому прикладі ми використали у якості функції зворотного виклику лямбда-функцію.
Якщо кількість елементів у послідовності буде різною, то в якості обмеження вибирається послідовність з мінімальною кількістю елементів:











Результат виконання:
[111, 222, 333]

Функція zip
Вбудована функція zip() на кожній ітерації повертає кортеж, що містить елементи послідовностей, які розташовані на однаковому зміщенні. Функція повертає об'єкт, що підтримує ітерації, а не список, як це було раніше у Python 2. Щоб отримати список у версії Python 3, необхідно результат передати до функції list(). Формат функції:

zip (<Послідовність 1> [..., <Послідовність N>])

Приклад:








Якщо кількість елементів в послідовності буде різною, то до результату потраплять тільки елементи, які існують у всіх послідовностях на однаковому зміщенні:





В якості ще одного прикладу переробимо нашу програму підсумовування елементів трьох списків і використовуємо функцію zip() замість функції map():









Функція filter
Функція filter() дозволяє виконати перевірку елементів послідовності.
Формат функції:

filter (<Функція>, <Послідовність>)

Якщо в першому параметрі замість назви функції вказати значення None, то кожен елемент послідовності буде перевірений на відповідність значенню True. Якщо елемент в логічному контексті повертає значення False, то його не буде додано до результату, що повертається. Функція повертає об’єкт, що підтримує ітерації, а не список або кортеж, як це було раніше в Python 2. Щоб отримати список у версії Python 3, необхідно результат передати в функцію list().
Приклад:




У першому параметрі можна вказати посилання на функцію. У цю функцію в якості параметра буде передаватися поточний елемент послідовності. Якщо елемент слід додати до повертаємого функцією filter() значення, то всередині функції зворотного виклику слід повернути значення True, в іншому випадку – значення False. Видалимо всі від'ємні значення зі списку:

Функція range()
Функція range () має наступний формат:

range ([<Початок>,] <Кінець> [, <Крок>])

Перший параметр задає початкове значення. Якщо параметр <Початок> не вказано, то за замовчуванням використовується значення 0. У другому параметрі вказується кінцеве значення. Слід зауважити, що це значення не входить до значень які повертаються. Якщо параметр <Крок> не вказано, то використовується значення 1. Функція повертає об'єкт, що підтримує ітераційний протокол. За допомогою цього об'єкта всередині циклу for можна отримати значення поточного елемента.
Наприклад:

Функція xrange ()
Функція xrange() - аналог range(), більш кращий для використання при послідовному доступі, наприклад, в циклі for або з ітераторами. вона повертає спеціальний xrange-об'єкт, який веде себе майже як список, породжуваний range(), але не зберігає в пам'яті всі видані елементи.



Функція eval()
У Python є вбудована функція eval(), яка виконує рядок з кодом і повертає результат виконання. Це дуже потужна, але в той же час і дуже небезпечна інструкція, особливо якщо рядки, які ви передаєте в eval, отримані не з перевіреного джерела. Ввівши певний код, зловмисник може, наприклад, завдати шкоди даним, що містяться на диску комп’ютера.
Функція eval()має наступний формат:

eval(expression, globals=None, locals=None)

Вона виконує вираз (програмний код) у рядку expression і повертає результат.
Приклад:
Завдання
1. Виконайте та поясніть результат роботи програми:

import math
def sqroot(x):
    # Знаходимо квадратний корінь
    return math.sqrt(x)

square_rt = lambda x: math.sqrt(x)

print(sqroot(49))     # 7.0
print(square_rt(64))  # 8.0

2. Виконайте та поясніть результат роботи програми:

foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
print(list(filter(lambda x: x % 3 == 0, foo)))
print(list(map(lambda x: x * 2 + 10, foo)))

Запитання
1. Які є два способи опису функцій в Python ?
2. Що таке функціональне програмування ?
3. Вкажіть найбільш поширені функції функціонального програмування 
4. Чому lambda функцію називають ананімною ?
5. Чи може lambda функція бути без параметрів ?
6. Яку дію виконує функція map ?
7. Чи можна функції map() передати кілька послідовностей ?
8. Яку дію виконує функція zip() ?
9. Яке призначення функції filter ?
10. Яка структура функції range ?
11. Яку дію виконує функція eval() ?



Комментариев нет:

Отправить комментарий