DEV Community

Cover image for An Introduction to Python Higher Order Functions
Brandon Brown
Brandon Brown

Posted on

An Introduction to Python Higher Order Functions

In a previous post, I created a guide for JavaScript higher-order functions to make dealing with array computations easier. In this blog post, I will do the same thing but with Python as the language. Hopefully with these examples, you'll find it easier to sort and manage lists in Python.

If you are interested in reading the JavaScript blog post, you may find it here.

All

The all method accepts an iterable as an argument and will return True only if all conditions of the iterable are True. Otherwise, the all method with return False.

arr = [1, 2, 3, 4, 5]

all(i > 0 for i in arr)
=> True

all( i < 4 for i in arr)
=> False

Filter

The filter method returns a new list of all elements of the list that satisfy a condition. This method accepts a function and an iterable as arguments. However, the filter method returns a filter object and not a list. Therefore, we have to convert the filter object into a list.

arr = [1, 2, 3, 4, 5]

def filter_function(x):
  return x > 2

list(filter(filter_function, arr))
=> [3, 4, 5]

# Alternatively
list(filter(lambda x: x > 2, arr))
=> [3, 4, 5]

Although the previous filter would work, it can be a little confusing since you must pass in a function as an argument. Python offers a great feature called list comprehension which is more widely used when filtering.

arr = [1, 2, 3, 4 5]

[x for x in arr if x > 2]
=> [3, 4, 5]

Using list comprehension is considered to be more "Pythonic" and should be used primarily. However, if your filter requires a multi-step process, the filter function is probably your best bet.

Next

The next method returns the first element of a list that satisfies a condition. This is similar to the find method in other languages. Next accepts an iterable as an argument. See the example below:

arr = [1, 2, 3, 4, 5]

next(x for x in arr if x > 2)
=> 3

If Python cannot find the element in the list, a StopIteration exception will be thrown and could crash your program if not handled correctly. Because of this, Python allows you to specify a default parameter.

arr = [1, 2, 3, 4, 5]

next(x for x in arr if x > 5)
=> StopIteration

next((x for x in arr if x > 5), None)
=> None

Hint: Do not forget to wrap your iterator in parentheses. Not doing so will cause a syntax error.

Includes

Python checks if elements exist in an array by using the "in" keyword. See the example below:

arr = [1, 2, 3, 4, 5]

1 in arr
=> True

6 in arr
=> False

For Each

To perform an action on every element of an array, Python uses the for loop. See the example below:

arr = [1, 2, 3, 4, 5]

for x in arr:
  print(f'Hello, I am {x}')
=> Hello, I am 1
Hello, I am 2
Hello, I am 3
Hello, I am 4
Hello, I am 5

It is important to note that changing the value of x does not change the original list.

arr = [1, 2, 3, 4, 5]

for x in arr:
  x = x * 2

print(arr)
=> [1, 2, 3, 4, 5]

There is a way to return an updated list; however, map (which we will talk about next) is a better option as opposed to the for loop. The for loop should primary be used to do something external for each item in the list.

Map

The map method returns a new list with all elements transformed by a function. This method accepts two arguments: a function and an iterable. Similar to filter, the map method returns a map object, so we must convert this map object to a list. See the example below:

arr = [1, 2, 3, 4, 5]
def square(x):
  return x * x

list(map(square, arr))
=> [1, 4, 9, 16, 25]

# Alternatively...
list(map(lambda x: x * x, arr))

However just like the filter method, you may use list comprehension to solve this problem. See the example below:

arr = [1, 2, 3, 4, 5]

[x * x for x in arr]
=> [1, 4, 9, 16, 25]

Again, list comprehension is the preferred method and is considered more "Pythonic."

Reduce

The reduce method reduces all values of a list into a single value. For example, the sum of a list can be considered as one of the simplest reducers since it takes all the elements of that list and returns a single value. This method is similar to filter and map in feel, but it is a little more complicated. The reduce method takes two required arguments and one optional argument. As its first required argument, the reduce method accepts a method that contains two arguments. The first argument of this inner function is the accumulator while the second is an element of the list. That is all for the inner method. The second argument of the reduce method is the list, and the third is an optional start parameter.

Additionally, the reduce function requires the Python library functools, so do not forget to import that library. I know this seems confusing, so hopefully the code will help you better understand.

import functools

def square_reducer(x, y):
  return x * y

arr = [1, 2, 3, 4, 5]

functools.reduce(square_reducer, arr)
=> 120

# Alternatively
functools.reduce(lambda x, y: x * y, arr)
=> 120

functools.reduce(square_reducer, arr, 2)
=> 240

# Alternatively
functools.reduce(lambda x, y: x * y, arr, 2)
=> 240

The first reduce function is the most straightforward. First we go to the first element and place it into the accumulator (x). Then we multiply the accumulator by the second element. So 1 * 2 = 2. Our accumulator value is 2. Next, we multiply the accumulator value by the third element (2 * 3). So we get a value of 6. We go on and on until we finish going through the entire array. In the end, this is what is happening:

1 * 2 * 3 * 4 * 5
=> 120

The second reduce function is doing the same exact thing but making use of a lambda function so we do not have to declare a reducer method separately.

The third function is doing the same as the first, however, it is starting with the accumulator set to 2. Therefore, this is the same as:

2 * 1 * 2 * 3 * 4 * 5
=> 240

Again, the fourth is doing the same as the third but using a lambda function.

Sort

The sort method returns a new sorted version of a list. The sorted method takes in one required argument and two optional arguments (reverse and key). The first argument is the list. The reverse optional parameter reverses the sorted list, and the key optional parameter is a function to base the list sort upon. See the examples below:

arr = [2, 1, 5, 3, 4]

sorted(arr)
=> [1, 2, 3, 4, 5]

sorted(arr, reverse=True)
=> [5, 4, 3, 2, 1]

students = [
  {'name': 'Jimmy', 'age': 15},
  {'name': 'Hector', 'age': 18},
  {'name': 'Paige', 'age': 16}
]

sorted(students, key=lambda x: x['age'])
=> [{'name': 'Jimmy', 'age': 15}, {'name': 'Paige', 'age': 16}, {'name': 'Hector', 'age': 18}]

Min

The min method searches a Python list for a minimum value. This method accepts one required parameter and three optional parameters. The required parameter is the iterable itself. Optionally, you may add more objects to this function as ongoing arguments. You may also sort using a key (similar to sorted method) and specify a default value. See the examples below:

arr = [1, 2, 3, 4, 5]

min(arr)
=> 1

min(0, -2, 1, 8, 5)
=> -2

students = [
    {'name': 'Jimmy', 'age': 15},
    {'name': 'Hector', 'age': 18},
    {'name': 'Paige', 'age': 16}
]

min(students, key=lambda x: x['age'])
=> {'name': 'Jimmy', 'age': 15}

min([], default=0)
=> 0

Max

The max method is identical to the min function; however, it finds the maximum value in an iterable. See the examples below:

arr = [1, 2, 3, 4, 5]

max(arr)
=> 5

max(0, -2, 1, 8, 5)
=> 8

students = [
    {'name': 'Jimmy', 'age': 15},
    {'name': 'Hector', 'age': 18},
    {'name': 'Paige', 'age': 16}
]

max(students, key=lambda x: x['age'])
=> {'name': 'Hector', 'age': 18}

max([], default=100)
=> 100

Conclusion

Higher order functions are wonderful to use and can save you a lot of time and headache if you are aware of them. I hope you find these methods helpful and easy to use. Happy coding!

Top comments (2)

Collapse
 
developerkaren profile image
Karen Efereyan

How I love pythonπŸ˜‹πŸ˜‹πŸ˜‹ but I'm now in love with JavaScript. Thanks for this Brandon

Collapse
 
brandonbrown4792 profile image
Brandon Brown • Edited

Good thinking. I have just updated the post to include those!