A Quick Guide to Higher Order Functions in Python

An Overview of First Class Functions and Lambda Functions

Python is a multi-paradigm programming language, with functional programming being one option, and functions in Python being treated as first-class objects.

In this article, we will explore the applications of treating functions as first-class objects and we will start by defining what is a first-class object.

Treating functions as First-Class Objects

We can define a first-class object as a program entity that can be:

  • Created at Runtime

  • Passed as an argument to a method or a function

  • Returned as a result of a function or a method

  • Assigned to a variable

This is the description of any object in Object Oriented Programming, and Python treats functions as objects natively.

def factorial(n):
    return 1 if n < 2 else n * factorial(n - 1)

print(type(factorial))
# <class 'function'>

As we can see, Python identifies the function as an Object, which means we can do this:

def factorial(n):
    return 1 if n < 2 else n * factorial(n - 1)

fact = factorial
print(fact(5))
# 123

print(list(map(factorial, range(11))))
# [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]

Python’s Higher-Order Functions

A high-order function is a Function that takes another Function as an argument or returns a Function, like Python’s Built-in function sorted.

fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']
print(sorted(fruits, key=len))
# ['fig', 'apple', 'cherry', 'banana', 'raspberry', 'strawberry']

Here, we pass the len function as an argument to the sorted function.

Some of the best higher-order functions are the famous map, filter and reduce functions, but list comprehension and generator expression have replaced them since they can do the job with easier and more compact syntax.

print(list(map(factorial, range(6))))
# [1, 1, 2, 6, 24, 120]

print([factorial(n) for n in range(6)])
# [1, 1, 2, 6, 24, 120]

print(list(map(factorial, filter(lambda n: n % 2, range(6)))))
# [1, 6, 120]

print([factorial(n) for n in range(6) if n % 2])
# [1, 6, 120]

How to be anonymous? Introducing the Lambda function

The Lambda Function is an anonymous function within a Python expression created by a Lambda expression.

Lambda Functions cannot be too complicated, since they usually are one-liners and used in an argument to another function. If you feel you need to use a while loop or a try-catch block, then you’re better off with a regular function.

# Sorting a list of words by their reversed spelling using lambda
fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']

print((fruits, key=lambda word: word[::-1]))
# ['banana', 'apple', 'fig', 'raspberry', 'strawberry', 'cherry']

Generally, if you find a piece of code hard to understand because of a lambda, the best solution is to refactor following these steps:

  • Document the lambda function to explain what it does

  • If you feel like the comment does not explain enough, think of a name for the lambda function

  • Convert the lambda to a regular function with a def statement

Conclusion

We saw here how can Python be efficient when coding in a functional style, this has been made possible by the higher-order functions, callables and some packages provided by Python.

Further Reading

Did you find this article valuable?

Support Algoryst's Corner by becoming a sponsor. Any amount is appreciated!