Higher Order Function in Python


Functions are Object:

As we know that in Python, functions are objects, that means ---

we can assign a function to a variable.

This assignment will not call the function, this will create a reference for that function. We can use this reference to execute the function or can be use to pass the function to another function as argument.

Example:

def myFun():
    print("hello from myFun")

myFun() # direct calling

f = myFun # creating a reference
f()  # calling the function using reference
                
OUTPUT:
hello from myFun
hello from myFun                    
                

As we can see in the above example, both ways are calling the same function.


Higher Order Function :

By the definition, a higher order function is a function that takes one or more function as argument or returns a function as result. This is one of the very important concept of functional programming. There so many built-in higher order functions are available in Python. We will look few of them in this tutorial.

Functions as Arguments :

We can pass functions as one of the arguments to another function.

EXAMPLE

def myfun():
    print("Hi, I am myfun")

# accepting function as argument
def fun(f):
    # calling the passes function
    f()

# driver code
ref = myfun # creating reference
# passing function as argument
fun(ref)
# OR
fun(myfun)  # Direct passing
                
OUTPUT :
Hi, I am myfun
Hi, I am myfun
        

As we can see, myfun() is a normal function. fun() is a function that accepts another function as argument and it executes the supplied function. We can see that the output reflects that.

ANOTHER EXAMPLE

def square(x):
    return x * x

def cube(x):
    return x * x * x

# accepting function as argument
def fun(f, v):
    # calling the passes function
    result = f(v)
    print(result)

# driver code
fun(square, 5)
fun(cube, 3)
      
OUTPUT :
25
27
 

In the above example, we can see that fun() can work with either square or cube with the given value.

Function as return value from a function :

As we know that functions are objects, we can also return a function from a function.

EXAMPLE

# normal function
def myfun():
    print("i am a normal function")

def fun():
    # returning a function
    return myfun

# ref will be reference to the returning function
ref = fun()
ref()  # calling the returning function
                
OUTPUT
i am a normal function
                

Returning Nested Function :

In Python, we can define a function within a function i.e. called nested function. We can also return a nested function from a function.

def fun():
    def myfun():
        print("i am a nested function")
    return myfun
# ref will be reference to the returning function
ref = fun()
ref()  # calling the returning function
                
OUTPUT
i am a nested function
                

ANOTHER EXAMPLE

# normal function which returns data
def add_two_nums(x, y):
    return x + y

# normal function which returns data
def add_three_nums(x, y, z):
    return x + y + z

# function which returns functions depending on the logic
def get_appropriate_function(num_len):
    if num_len == 3:
        return add_three_nums
    else:
        return add_two_nums


# driver code
args = [10, 20, 30]
num_len = len(args)
res_function = get_appropriate_function(num_len)
print(res_function(*args))

args = [10, 20]
num_len = len(args)
res_function = get_appropriate_function(num_len)
print(res_function(*args))
                
OUTPUT
60
30

Here, we can see that different function is returning depending upon the arguments.

To understand the two very important concept i.e. closures and decorators, you must know the concept of Higher Order Function.


Map, Filter and Reduce Functions :

map(), filter() and reduce() are built-in higher order functions.

Map() Function

map(function, *iterables) function accepts two parameters, first one is a function and second is iterable. It applies the function to each element of the sequence, and returns a map object.

EXAMPLE : Convert a list of strings in upper case.

For the above problem, we will use upper() function of string as mapping function in map.

map function will take every element from the list and pass to the upper() function.

map() function will return map type of object, we will use list() constructor to create a list from the map object.

mylist = ["c prowess", "c++ prowess", "java prowess", "prowessapps.in"]
mapped_list = map(str.upper, mylist)
print(mapped_list)
upper_list = list(mapped_list)
print(upper_list)
                
OUTPUT
 < map object at 0x016CE6D0 >
['C PROWESS', 'C++ PROWESS', 'JAVA PROWESS', 'PROWESSAPPS.IN']
            

In addition to the use of the built-in function, we can declare our own function as the mapping function.

As shown in the example below,we declare a function that takes a number and returns the square.

Calculate the square of each number in a list.

def find_square(x):
    return x * x
mylist = [2,3,4,5,6]
result = list(map(find_square, mylist))
print(result)
                
OUTPUT
[4, 9, 16, 25, 36]
                 

Actually, we can get it by just one line with the lambda function .

result = list(map(lambda x: x * x, [2, 3, 4, 5, 6]))
print(result)
                

Filter() Function

Like map() function, the filter(function, *iterables) function also receives two parameters, first one is a function and second is iterable. It applies the function to each element of the sequence, and decides whether to keep or discard the element based on whether the return value is True or False. filter() returns a filter type object.

EXAMPLE : filter the even numbers from a list.

For the above problem, we will declare a function checkEven(), that will return a boolean result, as mapping function in filter().

filter() function will take every element from the list and pass to the checkEven() function.

filter() function will return filter type of object, we will use list() constructor to create a list from the filter object.

def checkEven(x):
    if x % 2 == 0:
        return True
    else:
        return False
    
mylist = [12, 13, 14, 15, 16, 17]
filter_list = filter(checkEven , mylist)
print(filter_list)
even_list = list(filter_list)
print(even_list)
                
OUTPUT
< filter object at 0x01C6D070>
[12, 14, 16]
      

We can also do this by using lambda function .

mix_list = [12, 13, 14, 15, 16, 17]
filter_list = filter(lambda x : x %2 == 0 , mylist)
                

How filter() works when function argument is None :

There might be a situation when you are not passing any function(None) to filter() method.

Let's see with the example :

filter_list = list(filter(None , [1, 1.2, 0, False, True, "", 0.0, [], '0', 'hello']))
print(filter_list)
                
OUTPUT
[1, 1.2, True, '0', 'hello']
               

Here, in the above example we have a mix_list of numbers, boolean, string, nested list.

We are passing the mix_list to the filter() method with first parameter (filter function) as None.

In the above situation, every element of the mix_list will be checked for True or False with default identity.

We know that 0, empty list[], 0.0 and False are consider as False, that is why these values will be discard and rest will be filtered as output result.


Reduce() Function :

Till the Python version 2.X, reduce() function was the part of built-in functions. But, from Python 3.X, reduce() function is the part of module functools. So, before using it, first we have to import the module.

Syntax :

import functools
functools.reduce(function, iterable[, initializer])

First two arguments (function and sequence) are required arguments. This function will be applied to the item in an iterable and compute the cumulative final result.Third argument is optional.

Make sure that the function that is passed as argument to the reduce, takes exactly two elements.

How does the reduce() function work?

  • At the very first step, first two elements from the sequence are picked, pass to the function, and the result is obtained.
  • In the next step, the same function will apply with two elements, first element will be the result obtained from the previous call and second element will be the next value in the sequence.
  • The above process will continue until the sequence is not exhausted, and final result will be returned.

For example, if the iterable is [a,b,c,d] then we will get the result of operation between a and b, say the result is r1. In the next step result will be calculated between the previous result (r1) and the next value in the sequence c, say the result is r2, and final result will be calculated between r2 and d.

EXAMPLE : find the sum of all numbers in the list using reduce function.

import functools

def myadd(a, b):
    return a + b

result = functools.reduce(myadd, [1,2,3,4,5,6])
print(result)
                
OUTPUT
21         

We can do the same operation by using lambda function

from functools import reduce

result = reduce(lambda a, b: a + b, [1,2,3,4,5,6])
print(result)
                

The optional argument : initializer

Third argument to the reduce(), called initializer, is optional. If we pass the value to the initializer , then reduce() will use this value as first argument in very first call. It means that the first result will be obtained between initializer and the first item of iterable.

EXAMPLE :

from functools import reduce

mylist = [1,2,3,4,5,6,7,8,9,10]
result = reduce(lambda a, b: a + b, mylist, 100)
print(result)
                
OUTPUT
155

reduce() will raise a TypeError, if we pass empty iterable without initializer.

from functools import reduce
result = reduce(lambda a, b: a + b, [], 10)
print(result)

result = reduce(lambda a, b: a + b, [])
print(result)
                
OUTPUT
10
Traceback (most recent call last):
  File "C:/Users/daneyal/PycharmProjects/untitled/script.py", line 5, in 
    result = reduce(lambda a, b: a + b, [])
TypeError: reduce() of empty sequence with no initial value
                

As we have seen that we can find the sum of numbers by passing user-defined function to the reduce() or by using lambda function.

We can perform the same task by using operator.add() function with reduce().

from functools import reduce
from operator import add

result = reduce(add, [1,2,3,4,5])
print(result)
                

In-fact , in operator module there are many function that we can use with reduce().

from functools import reduce
from operator import add, sub, mul

sum = reduce(add, [1,2,3,4,5])
print(sum)

diff = reduce(sub, [30, 10, 10])
print(diff)

multi = reduce(mul, [1, 2, 3])
print(multi)
                
OUTPUT
15
10
6

EXAMPLE : find the maximum and minimum number

from functools import reduce
def my_min(a, b):
    return a if a < b else b

def my_max(a, b):
    return a if a > b else b

values = [3,6,8,2,4]
min = reduce(my_min, values)
max = reduce(my_max, values)
print(min)
print(max)
OUTPUT
2
8

Next chapter is Anonymous Function





Video Lecture



 




Training For College Campus

We offers college campus training for all streams like CS, IT, ECE, Mechanical, Civil etc. on different technologies like
C, C++, Data Structure, Core Java, Advance Java, Struts Framework, Hibernate, Python, Android, Big-Data, Ebedded & Robotics etc.

Please mail your requirement at info@prowessapps.in


Projects For Students

Students can contact us for their projects on different technologies Core Java, Advance Java, Android etc.

Students can mail requirement at info@prowessapps.in


CONTACT DETAILS

info@prowessapps.in
(8AM to 10PM):

+91-8527238801 , +91-9451396824

© 2017, prowessapps.in, All rights reserved