Skip to main content

Functional Programming in Python 3 - part 12

 Functional Programming in Python 3 - part 12

Table of content

  1. Functional programming

    1. Pure function

    2. Recursion

    3. Variables in immutable

    4. First class function

  2. Built-in high order function

    1. map function

    2. filter function

  3. Lambda Expressions

Functional Programming

Functional programming is a style of programming where almost every operation is performed with the help of functions. Functions are considered as first class citizens. Below are some of the guidelines for functional programming in python.

1. Pure Function : Every function is pure i.e. their behavior do not change for the same input. A pure function gives a consistent output (same output every time for the same input). 

The arguments passed to the function should not be modified. Below example illustrate the pure function implementation. A function takes string as argument and returns its lowercase version without modifying the passed object.

 
def pure_fun(input_string):
new_string = input_string.lower() # do not modify the argument
return new_string

s = "HELLO"
print(pure_fun(s))
 

Output

 
$ python3 pure_function.py
hello
$ 
 

2. Recursion : Use of recursion instead of looping construct like while and for. Following function takes an integer number as parameter and returns sum of all the integer till that number.

 
def n_sum(num):
if num == 1:
return 1
return num + n_sum(num-1)

print(n_sum(5))
 

Output

 
$ python3 recursive.py
15
$ 
 

Python has a maximum recursive depth for a function call on the call stack. The maximum recursive depth in python is 1000. In python we have a sys module that helps us understand the limit on recursion.

 
import sys

print(sys.getrecursionlimit())
 

Output

 
$ python3 recursive_depth.py
1000
$ 
 

Below example throws a RecursionError if the maximum limit is exceeded.

 
def n_sum(num):
if num == 1:
return 1
return num + n_sum(num-1)

print(n_sum(10))

print(n_sum(1000))
  

Output

 
$ python3 max_depth_exceed_error.py
55
Traceback (most recent call last):
File "/Users/shankernaik/code/py/django_app/django_project/a.py", line 8, in <module>
print(n_sum(1000))
File "/Users/shankernaik/code/py/django_app/django_project/a.py", line 4, in n_sum
return num + n_sum(num-1)
File "/Users/shankernaik/code/py/django_app/django_project/a.py", line 4, in n_sum
return num + n_sum(num-1)
File "/Users/shankernaik/code/py/django_app/django_project/a.py", line 4, in n_sum
return num + n_sum(num-1)
[Previous line repeated 995 more times]
File "/Users/shankernaik/code/py/django_app/django_project/a.py", line 2, in n_sum
if num == 1:
RecursionError: maximum recursion depth exceeded in comparison
$ 
  

We can also modify the limit using sys.setrecursionlimit(<integer_number>), but it is not recommended instead go for optimal solution.

 
import sys

print(sys.getrecursionlimit())

sys.setrecursionlimit(2000)

print(sys.getrecursionlimit())

Output

 
$ python3 set_limit.py
1000
2000
$ 
 

3. Variables are immutable : Every variable is treated as a immutable object, we should not modify them. In case we need to modified the data we need to create new variable.

 
a = 2
b = a*2
 

4. Functions are first-class citizens : First-class functions are functions that are treated as variable. i.e. we can pass them as argument, store them as value in the variable/datastructure. Python provides some higher order functions to make operations on iterable simple. 

Higher order functions are functions which takes first class function as parameter and can return a function. This is the difference between first-class functions and high-order functions.

Below example illustrates first-class function and higher order function.

 
def fun1(a):
return a*a

def fun2(fun):
a=fun(3)
return a

print(fun2(fun1))
 

Output

 
$ python3 fc_ho_function.py
9
$ 
 

Built in higher order function

a. map(<function>, <iterable_object>) : In-built map function map each element of iterable object to function and returns map_object which is iterable.

 
def get_square(a):
return a*a

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

result = map(get_square, ls)

print(result)

for i in result:
print(i)

Output

 
$ python3 map_function.py
<map object at 0x7f81c3fbb1f0>
1
4
9
16
25
$ 
 

b. filter(<function>, <iterable>) : The inbuilt filter() method filters the given sequence of data with the help of a function that tests each element in the sequence to be true or not.

 
def is_even(a):
if a%2 == 0:
return True
else:
return False

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

result = filter(is_even, ls)
print(result)

for i in result:
print(i)

Output 

 
$ python3 filter_example.py
<filter object at 0x7fe0f1e54160>
2
4
$ 
 

Lambda Expressions 

Functions without name (anonymous function). It is declared using lambda keyword. The syntax for declaring lambda expression :

                                      lambda <arguments>: <expression>

Below example illustrates the lambda expression: 

 
cube = lambda x: x * x*x
print(cube(7)) # calling the lambda function

L = [1, 3, 2, 4, 5, 6]
is_even = [x for x in L if x % 2 == 0] ##List comprehension
print(is_even) 
 

Output

 
$ python3 lambda_example.py
343
[2, 4, 6]
$ 
 

Thank you folks, if you like my post do check my other posts on Django with Python 3 and Ruby on Rails  on SWE crunch

Most viewed

Ruby on rails part 6 - Blocks , lambda, procs and closure

 Blocks , lambda, procs  and closure Table of content  1. Blocks 2. Lambda 3. Procs 4. Closure Blocks  Ruby blocks are little anonymous functions that can be passed into methods. Blocks are enclosed in a do-end statement or between brackets {} 
. Blocks can have multiple arguments
. The argument names are defined between two pipe | characters. Blocks are typically used with ‘each’ method which iterates over a list. Syntax of block using {} ['List of items'].each { | block arguments|  block body }  Syntax of block using do-end ['List of items'].each do | block arguments |      # block body end Example of block declared as do-end with each method.   [ 1 , 2 , 3 ].each do |num| puts num end     Output   $ ruby block_with_each.rb 1 2 3 $    Blocks can also be saved in variables or passed as argument to another function.   yield is a Ruby keyword that is used to call a block. When you use the yield keyword, the code inside the block will run. Example of saving a bl