Functional Programming
Functional Programming
Separation of Concerns - Functions operate on well defined data structures like lists and dictionaries. - Rather than belonging that data structure to an object.
Pure Functions - The idea here is that there's a separation between data of a program and the behavior of a program. - Has no side effects, does'nt change anything outside of the function, same input returns same output.
def multiply_by_two(li):
new_list = []
for item in li:
new_list.append (item * 2)
return new_list
print(multiply_by_two([1,2,3])) # [2,4,6]
Functions for Functional Programming Paradigm.
Higher-Order Functions(Built-in)
Python provides built-in higher-order functions: - map, filter, reduce, zip, lambda.
map
- Applies a function to each item in an iterable.
- map is useful when we have something that we can iterate over and want to apply a function.
def mul_by_five(item):
return item * 5
my_list = [1,2,3]
print(list(map(mul_by_five, my_list))) # [5, 10, 15]
print(my_list) # [1, 2, 3] original list is unchanged
map returns same number of items as input
names = ["alice", "bob", "charlie"]
print(list(map(str.capitalize, names))) # ['Alice', 'Bob', 'Charlie']
filter
- Filters items based on a condition.
- Filter is useful when want to filter out items from an iterable based on some condition.
def only_even(item):
return item % 2 == 0
def only_odd(item):
return item % 2 != 0
print(list(filter(only_even, my_list))) # [2]
print(list(filter(only_odd, my_list))) # [1, 3]
name = ["Alice", "Bob", "Charlie", "David", 'Ava']
def starts_with_a(name):
return name.startswith('A')
print(list(filter(starts_with_a, name))) # ['Alice', 'Ava']
zip
- Combines multiple iterables into tuples.
- zip works like a zipper, it takes two or more iterables and combines them into a single iterable of tuples
list1 = [1,2,3]
list2 = (10,20,30) #Doesn't have to be the same data type, just iterables
print(list(zip(list1, list2))) # [(1, 10), (2, 20), (3, 30)] {combines both}
reduce
- Reduces an iterable to a single value.
- reduce is useful when we want to reduce an iterable to a single value
from functools import reduce #functools is a module that contains higher order functions
# accumulator in simple terms is to two things together over and over
def accumulator(acc, item): # acc is accumulator, item is current item
return acc + item # 0 is the initial value of the accumulator
print(reduce(accumulator, list1, 0)) # 6 (0 + 1 + 2 + 3)
Lambda Expressions
- Anonymous one-time functions.
- Lambda expressions are one time anonymous functions, There's no name attached to this function.
syntax = lambda param: action(param)
print(list(map(lambda i: 2*i, my_list)))
print(list(filter(lambda i : i % 2 == 0, my_list)))
print(reduce(lambda acc, item: acc + item, list1))
Comprehensions
- Quick ways to create lists, sets, or dictionaries.
- Provide a way to create list, set or dict in Python instead of looping or appending
List Comprehensions
syntax: my_list = [expression for param in iterable if condition]
my_list1 = [char for char in 'hello']
print(my_list1) # ['h', 'e', 'l', 'l', 'o']
my_list2 = [num * 2 for num in range (50)]
print(my_list2) # [0, 2, 4, ..., 98]
my_list3 = [num ** 2 for num in range (10) if num % 2 == 0]
print(my_list3) # [0, 4, 16, 36,
Set Comprehensions
-Just like list comprehensions with curly braces {}
Dictionary Comprehensions
a_dict = {
'a': 1,
'b': 2,
'c': 3,
'd': 4
}
my_dict = {k:v**2 for k, v in a_dict.items() if v % 2 == 0} #just give value the expression
print(my_dict) # {'b': 4, 'd': 16}
my_dict1 = {num:num**2 for num in [1,2,3]}
print(my_dict1)
Functions as Variables
- Functions in Python can be treated like variables that hold other things — they can be assigned, passed around, and deleted.
def hello():
return 'hellooooo!!!!'
greet = hello # greet variable is now pointing to the function hello
del hello # delete the original function
print(greet()) # stil works because greet is pointing to the function
Higher-Order Functions
A higher-order function is any function that - accepts a function as a parameter, or - returns another function.
def hello():
def func():
return 'heyyy'
return func # returning the function itself, not calling it
def hello1(func): #It's a function that accepts inside of its parameters another function.
func() #calling the function passed as an argument
def greet():
print('greetingsss!!!!')
hello1(greet) # passing greet function as an argument to hello function
# hello function is designed to call other functions