Skip to content

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