Monday, December 28, 2015

Python Functional Programming

Python is classified as a "hybrid" language. It supports the functional programming paradigm, but equally supports imperative paradigms (both procedural and object-oriented).

Functions as Objects - Functions are first-class objects in Python, meaning they have attributes and can be referenced and assigned to variables.

High Order functions - Python also supports higher-order functions, meaning that functions can accept other functions as arguments and return functions to the caller.

List comprehension is nothing but a way of generating new lists from existing list(or from any other iterable data type).

Map - Most of the times when performing basic Operations on each element of a list or set ,we use the for loop to traverse over them and apply a operation on each element like,

>>> items = [1,2,3,4,5]
>>> sq = []
>>> for x in items:
...     sq.append(x ** 2)
>>> print sq
[1, 4, 9, 16, 25]
But Python provides better ways for doing these common operations day to day, one such built-in feature is map. The map(aFunction, aSequence) function applies a passed-in function to each item in an iterable object and returns a list containing all the function call results.

>>> items = [1,2,3,4,5]
>>> sq = []
>>> def sqr(x): return x**2
>>> list(map(sqr,items))
[1, 4, 9, 16, 25]

If we see the above snippet ,we can see that a list of items is passed to the map function along with a sqr function that is already written. The sqr function will square the element passed in the items list.

Since map expects a function to be passed , it is the most common place that is to be used with the lambda routine

>>> list(map((lambda x:x**2),items))
[1, 4, 9, 16, 25]

Map has some performance benefits when compared with the normal for loop that we write. More over map has some more additional benefits like taking arguments in sequence in parallel from a multiple sequence arguments like,

>>> list(map(pow,[2,3,4],[2,3,4]))
[4, 27, 256]

If the function passed is none, an identity function is used on them. if there are multiple arguments, map()returns a list consisting of tuples containing the corresponding items from all iterables.

>>> map(None,[1,2,3])
[1, 2, 3]

Filter –
The filter filters out items based on a test function which is a filter and apply functions to pairs of item and running result.

>>> for x in range(-5,5):
...     if x<0:
...             print x

The Similar can be implemented using the filter as,
>>> list( filter( (lambda x:x<0),range(-5,5) ))
[-5, -4, -3, -2, -1]

The reduce routine works in a different way. It applies the function to all the elements passed and then returns one result.

Consider we need to find a highest number in the series [1,3,5,2,6] , now if we have a function written to compare 2 elements as

f = lambda a,b: a if (a > b) else b

and pass this to the reduce routine as

>>> reduce(f,[1,3,5,2,4])

The reduce will take the first 2 arguments and use the function f on them , then take the obtained result with the 3 number and perform the function f on those both. This happens until last and a single value will be the result

The built-in reduce also allows an optional third argument placed before the items in the sequence to serve as a default result when the sequence is empty.

No comments :

Post a Comment