# Function Programming with Python

**What is functional programming?**

Functional programming languages are specially designed to handle symbolic computation and list processing applications. Functional programming is based on mathematical functions. Some of the popular functional programming languages include: Lisp, Python, Erlang, Haskell, Clojure, etc.

Recently, the use of functional programming has been on the rise. Thus, many traditionally imperative languages like Java and Python have started to support functional programming techniques. In this article I will be introducing some of these techniques to you with assuming you have basic understanding of functional programming. if you are not familiar with basic function programming, check this article on function programming.

**First-Class Functions**

Python functions are first class objects. Thus, we can assign them to variables, pass them as arguments to other functions, store them in other data structures such as dictionaries and use them as return values for other functions.

In the example below, we are assigning function to a variable. This assignment doesn’t call the function. It takes the function object referenced by shout and creates a second name pointing to it, Tell.

Show(defText): return Text.upper()OUTPUTHELLO WORLD

HELLO WORLD

Since functions are objects, we can assign the function `Show`

to any variable and then call that variable to refer to the function. For example, we can assign it to the variable `Tell.`

# Functions inside data structures

Same as other objects, Functions can also be stored inside Data Structures. For example, we can create a dictionary with mapping of `int`

to `func.`

This is useful for when the `int`

is a shorthand for a procedure to be performed.

*#INITIALIZING DICTIONARY*

dict = {

0*: func1,*

* *1*: **func2*

}

x = input() *#GET INTEGER VALUE FROM USER*

dict[x]() *#CALL THE FUNCTION RETURNED BY DICTIONARY ACCESS*

# Functions as arguments and return values

A function can take multiple arguments, these arguments can be objects, variables(of same or different data types) and functions.

Functions can also serve as arguments and return values of other functions. The functions that either accept or return functions are known as *higher-order functions** *and are an important part of functional programming.

Higher-order functions are extremely powerful. As explained deeply on Eloquent JavaScript:

Consider an example.

Let’s say we want to iterate over a list of items and print them sequentially. We can easily build an `iterate`

function:

**def** iterate(list_of_items):

for item in list_of_items:

** print**(item)

This might seem cool, but this is just one level of abstraction. What if we want to do something different (instead of print) when we iterate over the list?

That’s where higher-order functions come in. We can create a function `iterate_custom`

that takes in both a list to iterate and a function to be applied on each item:

**def** iterate_custom(list_of_items, custom_func):

** for** item **in** list_of_items:

custom_func(item)

Although this might seem trivial, it is immensely powerful.

We’ve moved up a layer of abstraction and made our code more reusable. Now, we can call the function not only when we want to print a list, but also do anything with the list that involves sequential iteration.

Functions can also be returned to make things simpler. Just like how we stored functions in a `dict`

, we can also use a function as control flow to decide the appropriate function. For example:

**def** add(x, y):

**return** x + ydef sub(x, y):

** return** x - ydef mult(x, y):

**return** x * ydef calculator(opcode):

**if **opcode == 1:

**return** add

** elif** opcode == 2:

**return** sub

**else**:

** return** mult my_calc = calculator(2) #MY CALC IS A SUBSTRACOTR

my_calc(5, 4) #RETURNS 5 - 4 = 1

my_calc = calculator(9) #MY CALC IS A MULTIPLLIER

my_calc(5, 4) #returns 5 x 4 = 20.

# Nested functions

Functions can be defined inside of other functions as well and these are aptly called *inner functions. *These are especially useful to make *helper functions *— small, reusable functions that support the main function as a sub-module.

Helper functions are handy when a problem requires a specific function definition (argument type or order) but it is easier to solve the problem without following the convention. A good example is from this lecture slide.

Let’s say you want to define a fibonacci function, `fib(n)`

, which takes a single argument, `n`

, and we have to return the `nth`

fibonacci number.

A possible way of defining such a function is with the use of a helper function that tracks the previous two terms of the fibonacci sequence (since a fibonacci number is simply the sum of the previous two fibonacci numbers).

**def** fib(n):

** def** fib_helper(fk1, fk, k):

**if** n == k:

** return** fk

**else**:

**return** fib_helper(fk, fk1+fk, k+1) if n <= 1:

**return** n

** else**:

** return** fib_helper(0, 1, 1)

Moving the calculation from function body to function argument is incredibly powerful because it reduces redundant calculation that may occur in a recursive approach.

# Lambda Expressions (Single Expression Functions)

How can we define a function without giving it any name? We can apply lambda function to define short and on -liner functions for example shown below.

`add = `**lambda** x, y: x + y

add(1, 2) *#RETURNS 2*

The behavior of this `add`

is exactly the same as the one defined using the traditional `def`

keyword earlier.

Note that lambda functions must be one-liners and must not contain a return statement written by the programmer.

In-fact, they always have an implicit return statement (in the above example, it would say `return x + y`

but we omit explicit return statements from lambda functions).

The lambda function is much more powerful and concise because we can also construct anonymous functions — functions without a name:

`(`

**lambda** x, y: x * y)(9, 10) #RETURNS 90

This is a handy method for whenever we need a function only once and need not use it later. For example, when filling up a dictionary:

**import** collections

pre_fill = collections.**defaultdict**(lambda: (0, 0))

#all dictionary keys and values are set to 0

We can now look at Map, Filter, and Reduce to appreciate lambda even more.

# Map, Filter, and Reduce

**1. Map**

`map`

is a function that takes a set of inputs and transforms them into another set based on a function specified. This is same as the `iterate_custom`

function . For example:

substract_1(defx):returnx - 1

scores = [10, 9, 8, 7, 6, 5]

new_scores =(map(substract_1, scores))list

#NEW SCORES ARE NOW [9, 8, 7, 6, 5, 4]

In Python 3, the `map`

function returns a `map`

object that can be typecast to a `list`

for us to make use of it. Now, instead of defining the `multiply_by_four`

function explicitly, we can define a `lambda`

expression:

`new_scores = list(map(lambda x: X-4, scores))`

## 2. Filter

`filter`

, as the name suggests, is a function that helps “filter” out unwanted items. For example, we may want to filter out all the odd numbers from `scores`

. We can do so using `filter`

:

`even_scores = `**list**(filter(**lambda** x: (x % 2 == 0), scores))

#even_scores = [6, 8]

Since the function supplied to `filter`

decides the acceptance of an item on a case-by-case basis, the function must return a `bool`

value (as seen in the lambda function above) and must be unary (take one input parameter).

## 3. Reduce

`reduce`

is a function to “summarize” or to get a “big-picture” of a set of data. For example, if we want to calculate the sum of all scores, we can use `reduce`

:

`sum_scores = `**reduce**((**lambda** x, y: x + y), scores)

#sum_scores = 32

This is much simpler than writing a loop. Note that the function supplied to `reduce`

requires two params: one represents the current item being inspected and one is the cumulative result of the operation being applied.

Note that the above just gets you started, although thoroughly, with functional programming in Python.

Moreover, You can practice and explore these concepts on this hacker-rank module.

Thank you for Reading and consider clap if you find it useful.