Wednesday, June 22, 2011

Functional Programming in Python


In C language we use functions, and normal parameters for function are variables and pointers. Did you ever think to pass another function as the parameter of a function? It is very complicated in C because we have to use complicated pointers for that purpose.

Being a very high level language, Python provides us a simple way to pass another function as a parameter to a function. This is called as higher order functions. Higher order functions have any of the following.
  • take one or more functions as an input
  • output a function
Python functions support this higher order functions and it is easy to implement. There are number of ways in which we can implement higher order function calls.

>>>def sqr(x): return x*x
...
>>>def cube(x): return x*x*x
...
>>>def compose(f, g,x): return f(g(x))
...
>>>compose(sqr, cube, 2)
64

Here 2 functions, sqr() and cube() are defined. Then we use these functions as parameters in the compose(). Compose takes sqr,cube and 2 as input and performs the action defined for it, i.e f(g(x)). This is an example where Python handles functions as first class objects.

We usually use the keyword ‘def’ to define functions. We can also implement functions that are not bound to a name. Python supports the creation of anonymous functions at runtime, using a construct called lambda. It is a very powerful concept that's well integrated into Python and is often used in conjunction with typical functional concepts like filter(), map() and reduce(). These functions are often called as functional programming tools. We will discuss about them after lambda.

How the lambda functions differ from normal functions? Take a look at the following codes,

#Normal function definition
>>> def f (x): return x**2
...
>>> print f(8)
64
#Lambda function definition
>>> g = lambda x: x**2
>>>
>>> print g(8)
64

Note that the lambda definition does not include a "return" statement, it always contains an expression which is returned. Also note that you can put a lambda definition anywhere a function is expected and you don't have to assign it to a variable at all.

Now we can discuss about the functional programming tools that are mentioned earlier in this post. The three built-in functions filter(), map() and reduce() are very useful when we use them with lists.

filter() has the syntax : filter(function, sequence). filter returns a sequence consisting of those items from the sequence for which function(item) is true. Have alook at the example code.

>>> def f(x): return x % 2 != 0 and x % 3 != 0
...
>>> filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]

Ultimately this codes finds prime numbers between 2 and 25. It takes the range as input and forms a list that includes only the values that satisfies the condition in parameter f(which is a function).

map() has the syntax : map(function, sequence). map calls the function(item) for all the values in the list. Example code is given below.

>>> def cube(x): return x*x*x
...
>>> map(cube, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
>>> map(cube, [1,2,3])
[1, 8, 27]

reduce() has the syntax as filter and map. It returns a single value constructed by calling the binary function function on the first two items of the sequence, then on the result and the next item, and so on.

>>> def add(x,y): return x+y
...
>>> reduce(add, range(1, 11))
55

This code is used to find the sum of numbers from 1 to 10.

We can use these three functions with lambda also. Take a look at the code given below.

>>> foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
>>>
>>> print filter(lambda x: x % 3 == 0, foo)
[18, 9, 24, 12, 27]
>>>
>>> print map(lambda x: x + 10, foo)
[12,28,19,32,27,34,18,22,37]
>>>
>>> print reduce(lambda x, y: x + y, foo)
139

Here filter filters the elements in the list ‘foo’ and outputs the list of elements that are divisible by 3. map is used to perform x+10 on each element in the list. reduce find the sum of elements of the list ‘foo’.

The functional programming is the key feature of Python and these functions are usually used for that purpose.

Thanks

AJAY

1 comment: