Similar presentations:
Елементи функціонального програмування
1. Python
Елементифункціонального
програмування
1
2. План
1.2.
3.
4.
5.
6.
7.
Функції як об'єкти першого класу (first-class
citizens)
Лямбда - вирази
Замикання
Функції вищого порядку, каррінг функцій
Декоратори
Функції filter, map, reduce
Модулі functools, оператор, itertools
2
3. Поняття функціонального програмування
Функціональне програмування - розділ дискретноїматематики і парадигма програмування, в якій процес
обчислення трактується як обчислення значень функцій в
математичному розумінні останніх (на відміну від функцій
як підпрограм в процедурному програмуванні).
Функціональне програмування передбачає обходитися
обчисленням результатів функцій від вихідних даних і
результатів інших функцій, і не передбачає явного
зберігання стану програми. Відповідно, не передбачає
воно і змінність цього стану (на відміну від імперативного,
де однією з базових концепцій є змінна, що зберігає своє
значення і дозволяє змінювати його в міру виконання
алгоритму)
3
4. Характерні риси функціонального програмування
Рішення задачі записується як сукупністьнезалежних від зовнішнього стану функцій
Функції як об'єкти першого класу
Імутабельність (незмінюваність) даних
Використання функцій вищого порядку
Каррінг і часткове застосування функцій
4
5. Функція як об'єкт першого класу
Об'єкт називають «об'єктом першого класу», якщо він:може бути збережений в змінній або структурах даних;
може передаватися в функцію як аргумент;
може бути повернутий з функції як результат;
може бути створений під час виконання програми;
внутрішньо самоідентифікований (незалежний від
іменування).
Термін «об'єкт» використовується тут в загальному
сенсі, і не обмежується об'єктами мови
програмування.
В Python, як і в функціональних мовах, функції є
об'єктами першого класу.
5
6. Приклад 1
def add(x,y):return x+y
def sub(x,y):
return x-y
def mul(x,y):
return x*y
def div(x,y):
return x/y
6
7. Приклад 1
operations ={'+' : add,
'-' : sub,
'*' : mul,
'/' : div,
'^' : pow}
7
8. Приклад 1
first = float(input('First number: '))operation = input('Operation: ')
second = float(input('Second number: '))
result = operations[operation](first,second)
print('Result:',result)
8
9. Лямбда вирази
Звичайне оголошення функції:def add(x, y):
return x + y
Використання лямбда - виразу (лямбдафункції, анонімної функції):
add = lambda x, y: x + y
9
10. Приклад 2
operations ={'+' : lambda x, y : x+y,
'-' : lambda x, y : x-y,
'*' : lambda x, y : x*y,
'/' : lambda x, y : x/y,
'^' : pow}
10
11. Замикання
Замикання (closure) У програмуванні - функція, в тілі якоїприсутні посилання на змінні, оголошені поза тілом цієї
функції в навколишньому коді і які не є її параметрами.
У разі замикання посилання на змінні зовнішньої функції
дійсні всередині вкладеної функції до тих пір, поки працює
вкладена функція, навіть якщо зовнішня функція закінчила
роботу, і змінні вийшли з області видимості.
Замикання пов'язує код функції з її лексичним оточенням
(місцем, в якому вона визначена в коді). Лексичні змінні
замикання відрізняються від глобальних змінних тим, що
вони не займають глобальний простір імен. Від змінних в
об'єктах вони відрізняються тим, що прив'язані до функцій,
а не об'єктів.
В Python будь-які функції (в тому числі і лямбда - вирази),
оголошені всередині інших функцій, є повноцінними
замиканнями.
11
12. Приклад 3
def add(x):def two_add(y):
return x+y
return two_add
print(add(402)(45))
12
13. Функції вищого порядку
Функція вищого порядку - функція, щоприймає в якості аргументів інші функції або
повертає іншу функцію в якості результату.
Основна ідея полягає в тому, що функції
мають той же статус, що й інші об'єкти даних.
Каррінг (currying) - перетворення функції від
багатьох аргументів на функцію, що бере свої
аргументи по одному. Це перетворення було
введено М. Шейнфінкель і Г. Фреге і отримало
свою назву на честь Х. Каррі.
13
14. Приклад 4
def add(x):def two_add(y):
return x+y
return two_add
add_to_ten=add(10)
print(add_to_ten(2))
print(add_to_ten(12.5))
14
15. Приклад 5
elem = lambda value, next: {'value': value,'next': next}
to_string = lambda head: '' if head is None \
else str(head['value'])+' '
+to_string(head['next'])
values = elem(1,elem(2,elem(3,None)))
print(to_string(values))
15
16. Декоратори
Декоратор в Python - функція, яка приймає якпараметр іншу функцію (або клас) і повертає
нову, модифіковану функцію (або клас), яка її
замінює.
Крім того, поняття функцій вищого порядку часто
застосовується і для створення декораторів:
часто потрібно, щоб декоратор брав ще якісь
параметри, крім об'єкта що модифікується. В
такому випадку створюється функція, що
створює і повертає декоратор, а при застосуванні
декоратора замість вказівки імені функціїдекоратора дана функція викликається.
16
17. Приклад 6
def decorator(fn):def decorated_fn(*args, **kwargs):
print('Decorated function says:')
fn(*args, **kwargs)
print()
return decorated_fn
def hello():
print('Hello!')
#hello = decorator(hello)
hello()
17
18. Приклад 7
def decorator(fn):def decorated_fn(*args, **kwargs):
print('Decorated function says:')
fn(*args, **kwargs)
print()
return decorated_fn
@decorator
def hello():
print('Hello!')
hello()
18
19. map, filter, reduce
Трьома класичними функціями вищого порядку, що з'явилисяще в мові програмування LISP, які приймають функцію і
послідовність, є map, filter і reduce.
map застосовує функцію до кожного елементу
послідовності. В Python 2 повертає список, в Python 3 об'єкт-ітератор.
filter залишає лише ті елементи послідовності, для яких
задана функція істинна. В Python 2 повертає список, в
Python 3 - об'єкт-ітератор.
reduce (в Python 2 вбудована, в Python 3 знаходиться в
модулі functools) приймає функцію від двох аргументів,
послідовність і опціональне початкове значення і обчислює
згортку (fold) послідовності як результат послідовного
застосування даної функції до поточного значення (так
званому акумулятору) і наступному елементу
послідовності.
19
20. Приклад 8
values = [2, 4, 8, 15, 42]for square in map(lambda x: x**2,
values):
print(square)
square = list(map(lambda x: x**2, values))
print(square)
20
21. Приклад 9
numbers = [3, 2, -1, 0, 15, -8, -7, 3, -3, 8]positive_numbers = filter(lambda x: x > 0,
numbers)
print(list(positive_numbers))
21
22. Приклад 10
from functools import reducenumbers = [3, 2, 1, 8, -3, -2]
product = reduce(lambda x, y: x * y,
numbers)
print(product)
22
23. Модуль functools
Модуль functools містить велику кількість стандартнихфункцій вищого порядку. Деякі з них :
lru_cache - декоратор, який кешує значення функцій,
які не змінюють свій результат при незмінних
аргументах; корисний для кешування даних,
мемоізаціі (збереження результатів для повернення
без обчислення функції) значень рекурсивних функцій
(наприклад, такого типу, як функція обчислення n - го
числа Фібоначчі) і т. д .;
partial - часткове застосування функції (виклик
функції з меншою кількістю аргументів, ніж вона
очікує, і отримання функції, яка приймає параметри
що залишилися).
23
24. Приклад 11
from functools import lru_cache@lru_cache(maxsize=None)
def fibonacci(index):
if index < 2:
return 1
else:
return fibonacci(index - 1) + fibonacci(index - 2)
for i in range(1, 1000):
print(fibonacci(i))
24
25. Приклад 12
from functools import partialdef add(x,y):
return x+y
add_to_ten=partial(add,10)
print(add_to_ten(2))
print(add_to_ten(12.5))
25
26. Модуль itertools
Модуль itertools містить функції для роботи зитераторами і створення ітераторів. Деякі з них :
product - декартовій добуток ітераторів (для
уникнення вкладених циклів for);
permutations - генерація перестановок;
combinations - генерація сполучень;
combinations_with_replacement - генерація
розміщень;
chain - поєднання декількох ітераторів в один;
takewhile - отримання значень послідовності, поки
значення функції - предиката для її елементів
істинно;
dropwhile - отримання значень послідовності
починаючи з елемента, для якого значення функції 26
предиката перестане бути істинно.
27. Приклад 13
from itertools import productfor i in range(1,5):
for j in range(1,5):
#for i, j in product(range(1,5),range(1,5)):
print('{}x{}={}'.format(i,j,i*j))
27
28. Приклад 14
from itertools import chainfor i in chain(range(2), range(3)):
print(i)
28
29. Приклад 15
from itertools import permutations,combinations,
combinations_with_replacement
print(list(permutations('ABC', 2)))
print()
print(list(combinations('ABC', 2)))
print()
print(list(combinations_with_replacement('ABC', 2)))
29
30. Приклад 16
from itertools import takewhile, dropwhilenumbers = [1, 4, 6, 4, 1]
predicate = lambda x: x < 5
for value in takewhile(predicate, numbers):
print(value)
print()
for value in dropwhile(predicate, numbers):
print(value)
30
31. Модуль operator
Модуль operator містить функції, яківідповідають стандартним операторам.
31
32.
Операторa (точніше not not a)
not a
-a
a+b
a-b
a*b
a/b
a%b
~a
a&b
a^b
a|b
Функція
truth(a)
not_(a)
neg(a)
add(a, b)
sub(a, b)
mul(a, b)
div(a, b)
mod(a, b)
invert(a)
and_(a, b)
xor(a, b)
or_(a, b)
32
33.
Операторa << b
a >> b
seq1 + seq2
seq * i
o in seq
o[k]
o[k] = v
del o[k]
seq[i:j]
seq[i:j] = values
del seq[i:j]
Функція
lshift(a, b)
rshift(a, b)
concat(seq1, seq2)
repeat(seq, i)
contains(seq, o)
getitem(o, k)
setitem(o, k, v)
delitem(o, k)
getslice(seq, i, j)
setslice(seq, i, j, values)
delslice(seq, i, j)
33
34. Приклад 17
from operator import neg, mul, lefrom functools import reduce, partial
print(list(map(neg, [2, 4, 8, 9, 1])))
print(reduce(mul, [3, 4, 5]))
print(list(filter(partial(le, 5), [5, 4, 8, 1, 3, 10])))
34