0% found this document useful (0 votes)
12 views53 pages

Functional Programming in Python Guide

Uploaded by

Mohamed Sayed
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views53 pages

Functional Programming in Python Guide

Uploaded by

Mohamed Sayed
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Advanced Python

Chapter 03: Functional Programming in Python

• Introduction to functional programming

• Functional programming Principals

• Lambda functions

• Map, filter, and reduce functions

• Generators and iterators (Yields and Next function)

• Decorators
Advanced Python

Functional Programming in Python

Introduction to functional programming

Python supports multiple programming paradigms:

• Imperative programming

• Functional programming

• Object-oriented programming (OOP)

• Procedural programming

• Declarative programming
Advanced Python

Functional Programming in Python

● Functional programming (FP) is a programming paradigm that focuses on the


use of functions to solve programming problems.
● Functional Programming treats computation as the evaluation of mathematical
functions and avoids changing state or mutable data.
Advanced Python

Functional Programming Principles

● Core Principles of Functional Programming Functional programming is built


upon several fundamental principles that guide its approach to software
development:
● Pure Functions
● Immutability
● First-Class Functions
● Higher-Order Functions (HOFs)
● Recursion
● Lazy Evaluation
● Function Composition
Advanced Python

Functional Programming Principles

● Pure functions: In functional programming, pure functions are functions that


have no side effects and always return the same output given the same input.
Pure functions are easier to reason about, test, and parallelize.
● Characteristics of Pure Functions:
● Deterministic: Always returns the same output for the same input.
● No Side Effects: Does not modify global variables, perform I/O operations,
or change the state of objects passed as arguments.
● Testable: Easy to unit test as their behavior is isolated and predictable.
Advanced Python

Functional Programming Principles

Pure functions:

Example 01:

def square(x):

return x ** 2

sequare(3)
Advanced Python

Functional Programming Principles

Pure functions:

Example 02:

def add(a, b):

return a + b

result = add(5, 3) # Returns 8


Advanced Python

Functional Programming Principles

Pure functions
Example 03:

def multiply(a, b):

return a * b

result = multiply(4, 7) # Returns 28


Advanced Python

Functional Programming Principles

Pure functions

Example 04:

def concatenate_strings(s1, s2):

return s1 + s2

result = concatenate_strings("Hello, ", "world!") # Returns "Hello, world!"


Advanced Python

Functional Programming Principles

● Impure Functions: An impure function, conversely, may produce different


outputs for the same input or cause side effects. These functions often interact
with external state, such as global variables, databases, or user input.
● While functional programming encourages minimizing impure functions, they
are often necessary for real-world applications involving I/O, database
interactions, or user interfaces.
Advanced Python

Functional Programming Principles

● Impure Function Example:


counter = 0
def increment(x):
global counter
counter += x
return counter

print(increment(5)) # Output: 5
print(increment(5)) # Output: 10 (depends on previous state!)
Advanced Python

Functional Programming Principles

● Immutability: Data structures are not modified after creation. Instead, any
operation that would typically alter a data structure in an imperative paradigm
results in the creation of a new data structure with the desired changes. This
prevents unexpected side effects and simplifies concurrent programming.
Advanced Python

Functional Principles

● First-Class Functions: Functions are treated as first-class citizens, meaning


they can be assigned to variables, passed as arguments to other functions, and
returned as values from other functions. This flexibility is crucial for building
higher-order functions and enabling dynamic behavior.
Advanced Python

Functional Programming Principles

● Higher-order functions(HOFs): Python supports higher-order functions, which


are functions that take one or more functions as arguments or return a function
as their result.
● HOFs are powerful abstractions that can be used to create more generic , flexible
and reusable code.
Advanced Python

Functional Programming Principles


Higher-order functions Example:

def apply_operation(func, x, y):

return func(x, y)

def add(x, y):

return x + y

def multiply(x, y):

return x * y

result = apply_operation(add, 2, 3) # result is 5

result = apply_operation(multiply, 2, 3) # result is 6


Advanced Python

Functional Programming Principles

● Recursion: In functional programming, recursion is often preferred over


explicit loops for iterative processes. It involves a function calling itself
until a base condition is met.
Advanced Python

Functional Programming Principles

● Lazy Evaluation: Values are computed only when they are actually
needed, rather than immediately. This can lead to performance
optimizations and the ability to work with potentially infinite data streams
(e.g., using generators and iterators in Python).
Advanced Python

Functional Programming Principles

● Function Composition: This involves combining simpler functions to build


more complex ones. By chaining functions together, data flows through a
series of transformations, leading to clear and modular code.
Advanced Python

Functional Programming : lambda function


Lambda function

● A lambda function, also known as an anonymous function, is a small, single-expression


function that doesn't have a name. Lambda functions can be defined inline within
expressions or passed as arguments to other functions.

● They are particularly useful for short, throwaway functions that are used as arguments to
higher-order functions.
● A lambda function can take any number of arguments, but can only have one expression.

Syntax:

lambda arguments: any expression


Advanced Python

Functional Programming : lambda function

● Key Characteristics:

● Anonymous: They do not have a name.

● Single Expression: They can only contain one expression, not multiple

statements, assignments, or loops.

● Concise: Ideal for simple operations where a full function definition would be verbose.

Syntax:

lambda arguments: any expression


Advanced Python

Functional Programming : lambda()

Example 01:

square = lambda x: x ** 2

result = square(5) # result is 25

Example 02:

add = lambda x, y: x + y

result = add(2, 3)

print(result) # prints 5
Advanced Python

Functional Programming : lambda()

Example 03:

multiply = lambda x, y, z: x * y * z

result = multiply(2, 3, 4)

print(result) # prints 24
Advanced Python

Functional Programming : lambda()

Example 04: Example 05:

Max = lambda a, b : a if(a > b) else b str1 = 'welcome'

print(Max(1, 2)) upper = lambda string: [Link]()

print(upper(str1))
Advanced Python

Functional Programming : lambda()

Example 06:

def myfunc(n):

return lambda a : a * n

mydoubler = myfunc(2)

mytripler = myfunc(3)

print(mydoubler(13))

print(mytripler(13))
Advanced Python

Functional Programming: lambda()

Example 07: (with list comprehension)

l= [lambda arg=x: arg * 10 for x in range(1, 5)]

for item in l:

print(item()) # [10,20,30,40]

Note: A Python list comprehension consists of brackets containing the expression, which is executed
for each element along with the for loop to iterate over each element in the Python list.
Advanced Python

Functional Programming

Example 08:
List = [[2,3,4],[1, 4, 16, 64],[3, 6, 9, 12]]

sortList = lambda x: (sorted(i) for i in x)

secondLargest = lambda x, f : [y[len(y)-2] for y in f(x)]

res = secondLargest(List, sortList)

print(res) #output: [3, 16, 9]

● It uses lambda functions to sort each sublist and find the second-largest element in
each sublist. The result is a list of second-largest elements, which is then printed.
The output displays the second-largest element from each sublist in the original list.
Advanced Python

Functional Programming

True or False:
1. Lambda functions can have multiple expressions.
2. Lambda functions have only one argument.
Advanced Python

Functional Programming : map()

map():

● In Python, map() is a built-in function that applies a given function to each


element of an iterable and returns a new iterable with the transformed values.
The map() function is useful for performing operations on all elements of a list,
tuple, or other iterable without having to write a loop.
● function returns a map object(which is an iterator) of the results after applying
the given function to each item of a given iterable (list, tuple etc.)
Advanced Python

Functional Programming : map()

Syntax:

map(function, iterable)

Where function is the function to apply to each element of the iterable, and
iterable is the object that you want to apply the function to.
Advanced Python

Functional Programming : map()

Example 01:
my_list = [1, 2, 3, 4, 5]

squared_list = list(map(lambda x: x ** 2, my_list))

print(squared_list) # prints [1, 4, 9, 16, 25]


Advanced Python

Functional Programming : map()

Example 2: Converting strings in a list to uppercase using map()


my_list = [‘mango', 'banana', 'cherry‘, ’kiwi’, ‘grape’]

uppercase_list = list(map(lambda x: [Link](), my_list))

print(uppercase_list) # prints ['MANGO', 'BANANA', 'CHERRY‘, ’KIWI’,


‘GRAPE’]
Advanced Python

Functional Programming : map()

Example 3: Finding the length of each string in a list using map()


my_list = ['apple', 'banana', 'cherry‘, ‘kiwi’, ‘grape’]

length_list = list(map(lambda x: len(x), my_list))

print(length_list) # prints [5, 6, 6, 4, 5]


Advanced Python

Functional Programming : map()

Example 4: Using map() with multiple iterables


my_list1 = [1, 2, 3]

my_list2 = [10, 20, 30]

product_list = list(map(lambda x, y: x * y, my_list1, my_list2))

print(product_list) # prints [10, 40, 90]


Advanced Python

Functional Programming: map()

Example 5: Using map() with Strings

# List of strings

l = ['sat', 'bat', 'cat', 'mat']

# map() can listify the list of strings individually

test = list(map(list, l))

print(test)

#[['s', 'a', 't'], ['b', 'a', 't'], ['c', 'a', 't'], ['m', 'a', 't']]
Advanced Python

Functional Programming: filter()

filter():

● In Python, filter() is a built-in function that applies a given function to each element of
an iterable and returns a new iterable with only the elements that satisfy the condition.
Returns: an iterator that is already filtered.

Syntax:

filter(function, iterable)

Where function is the function to apply to each element of the iterable, and iterable is the object
that you want to apply the function to.
Advanced Python

Functional Programming : filter()

Example 1: Filtering out even numbers from a list using filter()


my_list = [1, 2, 3, 4, 5]

even_list = list(filter(lambda x: x % 2 == 0, my_list))

print(even_list) # prints [2, 4]


Advanced Python

Functional Programming : filter()

Example 2: Filtering out strings that contain a specific substring using filter()

my_list = ['apple', 'banana', 'cherry']

filtered_list = list(filter(lambda x: 'a' in x, my_list))

print(filtered_list) # prints ['apple', 'banana']

Example 3: Filtering out non negative numbers from a list using filter()

my_list = [-2, 0, 3, -5, 6]

positive_list = list(filter(lambda x: x >= 0, my_list))

print(positive_list) # prints [0, 3, 6]


Advanced Python

Functional Programming: filter()

Example 4: Filtering out not empty strings from a list using filter()

my_list = ['apple', 'banana', 'cherry‘, ‘kiwi’, ‘grape’]

nonempty_list = list(filter(lambda x: x != '', my_list))

print(nonempty_list) # prints ['apple', 'banana', 'cherry‘, ‘kiwi’, ‘grape’]

Example 5: Using filter() with multiple conditions

my_list = [1, 2, 3, 4, 5]

filtered_list = list(filter(lambda x: x > 2 and x < 5, my_list))

print(filtered_list) # prints [3, 4]


Advanced Python

Functional Programming: filter()

Example 6: filter out numbers that are multiple of 3


def is_multiple_of_3(num):
return num % 3 == 0
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = list(filter(lambda x: is_multiple_of_3(x), numbers))
print(result)

#[3, 6, 9]
Advanced Python

Functional Programming: reduce()

reduce() function

● In Python, reduce() is a built-in function that applies a given function to the elements of
an iterable and returns a single value. The reduce() function is useful for performing
operations that combine multiple elements of a list, tuple, or other iterable.

Syntax:

reduce(function, iterable[, initializer])


Where function is the function to apply to each element of the iterable, and iterable is the object that you want to
apply the function to. The initializer parameter is optional and is used to specify an initial value for the
reduction.
Advanced Python

Functional Programming : reduce()

Example 1: Finding the sum of a list using Working


reduce()
Iteration 1: x = 1 (first element), y = 2, result = 3
from functools import reduce
Iteration 2: x = 3 (previous result), y = 3, result = 6
my_list = [1, 2, 3, 4, 5]
Iteration 3: x = 6 (previous result), y = 4, result = 10
sum = reduce(lambda x, y: x + y,
my_list) Iteration 4: x = 10 (previous result), y = 5, result =
15
print(sum) # prints 15
Advanced Python

Functional Programming : reduce()

Example 2: Finding the product of a list using reduce()

from functools import reduce

my_list = [1, 2, 3, 4, 5]

product = reduce(lambda x, y: x * y, my_list)

print(product) # prints 120

Example 3: Finding the maximum element of a list using reduce()

from functools import reduce

my_list = [1, 5, 3, 4, 2]

maximum = reduce(lambda x, y: x if x > y else y, my_list)

print(maximum) # prints 5
Advanced Python

Functional Programming: reduce()

Example 4: Combining strings in a list using reduce()


from functools import reduce
my_list = [‘mango', 'banana', 'cherry']
combined_string = reduce(lambda x, y: x + ', ' + y, my_list)
print(combined_string) # prints ‘mango, banana, cherry'
Example 5: Using reduce() with an initial value
from functools import reduce
my_list = [1, 2, 3, 4, 5]
sum = reduce(lambda x, y: x + y, my_list, 10)
print(sum) # prints 25
Advanced Python

Functional Programming

Generator

● A generator function is a special type of function that returns an iterator, which can be
iterated over using the yield keyword.
● A generator function in Python is defined like a normal function, but whenever it needs
to generate a value, it does so with the yield keyword rather than return. If the body of a
def contains yield, the function automatically becomes a Python generator function.
● Each time the yield statement is encountered, the function's state is saved, and the
yielded value is returned.
● It can have one or more yield.
● It return a generator object
Advanced Python

Functional Programming

Generator

● The next() function is used to retrieve the next value from the iterator.
● Python Generator functions return a generator object that is iterable, i.e., can
be used as an Iterator. Generator objects are used either by calling the next
method of the generator object or using the generator object in a “for in” loop.
● Standard Functions: Compute a value and return it once. They use the return
statement.
● Generators: Use the yield statement to return values one at a time, allowing
iteration over a sequence of values without storing the entire sequence in
memory.
Advanced Python

Functional Programming

Example 00:
# Using the generator
def test (x, y, z):
gen = test(5,6,7)
yield x
print(next(gen)) #
yield y Output: 5
yield z print(next(gen)) #
Output: 6
print(next(gen)) #
Output: 7
Advanced Python

Functional Programming

Example 01: # Using the generator

def number_generator(n): gen = number_generator(5)

print(next(gen)) # Output: 0
for i in range(n):
print(next(gen)) # Output: 1
yield i
print(next(gen)) # Output: 2

print(next(gen)) # Output: 3

print(next(gen)) # Output: 4
Advanced Python

Functional Programming

Example 03: # Using the generator


def square_generator(n): gen = square_generator(5)
for i in range(n): print(next(gen)) # Output: 0
yield i ** 2 print(next(gen)) # Output: 1
print(next(gen)) # Output: 4
print(next(gen)) # Output: 9
print(next(gen)) # Output: 16
Advanced Python

Functional Programming

Example 04: # Using the generator


def even_numbers(n): gen = even_numbers(10)
for i in range(n): print(next(gen)) # Output: 0
if i % 2 == 0: print(next(gen)) # Output: 2
yield i print(next(gen)) # Output: 4
print(next(gen)) # Output: 6
print(next(gen)) # Output: 8
Advanced Python

Functional Programming

Decorators

● In Python, a decorator is a function that takes another function as input and


extends the behavior of the latter function (function that is passed as an
argument to the decorator) without modifying its source code.
● A decorator allows you to modify or add functionality to a function dynamically
at runtime.
Advanced Python

Functional Programming

Example 00:

def decorator(func): def greet():


def wrapper(): print("Hello, world!")
print("Before function result = decorator(greet)
execution")
# result() # Equivalent to calling wrapper()
func()
result()
print("After function execution")
return wrapper
Advanced Python

Functional Programming

Example 01:

def decorator(func): @decorator


def wrapper():
def greet():
print("Before function execution")
print("Hello, world!")
func()
greet()
print("After function execution")

return wrapper
Advanced Python

Functional Programming

Example 02: Decorator that converts the result to uppercase

def uppercase_decorator(func): @uppercase_decorator


def wrapper(): def greet():
result = func() return "Hello, world!"
return [Link]() # result = uppercase_decorator(greet)
return wrapper # print(result())
print(greet()) # Output: "HELLO, WORLD!"

You might also like