Yos Riady software craftsman 🌱

Python Higher Order Functional Programming

In this post, I’d like to provide an overview to built-in higher-order python functions such as map, filter, reduce and how you can use them to simplify the overall structure of your code.

Let’s start by defining a simple problem:

Given a list of integers, I want to be able to obtain a list of booleans of whether or not the integers are even.

We can write a traditional solution this way:

data = [1,2,3,4,5]
result = []
for i in range(0,len(data)):
    if data[i]%2==0:
        result[i] = True
    else:
        result[i] = False

The code above works, but it seems too verbose for our liking. In Functional programming, we have the following in our arsenal:

  • Immutable data
  • First-class functions
  • Higher-order functions
  • Pure functions
  • Recursion, tail recursion
  • Iterators, sequences, lazy evaluation, pattern matching, monads

Now, let’s see an alternative solution with the map higher-order function and lambda functions (anonymous functions):

map(function, sequence[, sequence, …]) -> list

Return a list of the results of applying the function to the items of the argument sequence(s). If more than one sequence is given, the function is called with an argument list consisting of the corresponding item of each sequence, substituting None for missing values when not all sequences have the same length. If the function is None, return a list of the items of the sequence (or a list of tuples if more than one sequence).

Lambda functions are anonymous functions. What does that mean? They’re functions without a declared name. Let’s look at an example so you can see what I mean. In the above example, we can sort alphabetically without defining the iseven function like so:

result = map(lambda n: n%2==0, data)

As you can see, higher order functions lend to more concise solutions. Let’s take a look at another problem:

Given a list of integers, I want to be able to obtain a list of just the even numbers.

Traditional solution:

data = [1,2,3,4,5]
result = []
for i in range(0,len(data)):
    if data[i]%2==0:
        result.append(data[i])

An alternative solution with the filter higher-order function:

filter(function or None, sequence) -> list, tuple, or string

Return those items of sequence for which function(item) is true. If function is None, return the items that are true. If sequence is a tuple or string, return the same type, else return a list.

result = filter(lambda x: x%2==0,data)

Finally, we have reduce, also known as accumulate in some languages. This function is an abstraction above the fold method, if you’re familiar with functional programming. reduce takes in an iterable and returns one value.

reduce(function, sequence[, initial]) -> value

Apply a function of two arguments cumulatively to the items of a sequence, from left to right, so as to reduce the sequence to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). If initial is present, it is placed before the items of the sequence in the calculation, and serves as a default when the sequence is empty.

reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
# evaluates to ((((1+2)+3)+4)+5)

As you can see, we have a lambda function of two arguments. The left argument x is the accumulated value and y is the next iterator value.

To sum up, the use higher order functions is not limited to functional languages. Other languages such as Python, Ruby, and Javascript either have them natively or can be obtained with external libraries such as underscore.js for Javascript. Using functional ideas in generous measure can lead to more concise code.


P.S.

Alternatively, you can solve the first problem using list comprehensions:

result = [x % 2 == 0 for x in data]

Author

Yos is a software craftsman based in Singapore.

📬 Subscribe to my newsletter

Get notified of my latest articles by providing your email below.


Going Serverless book

Interested to find out more about serverless? Going Serverless teaches you how to build scalable applications with the Serverless framework and AWS Lambda. You'll learn how to design, develop, test, deploy, and secure Serverless applications from planning to production.

Learn More →