How To Replace Your Python For Loops with Map, Filter, and Reduce
Write more semantic code with functional programming
Do you ever look at your code and see a waterfall of for loops? Do you find yourself having to squint your eyes and lean towards your monitor to get a closer look?
I know I do.
For loops are a Swiss army knife for problem-solving, but, when it comes to scanning code to get a quick read of what you’ve done, they can be overwhelming.
What are Map, Filter, and Reduce?
Reviewing my previously written code, I realized that 95% of the time when looping through strings or arrays I do one of the following: map a sequence of statements to each value, filter values that meet specific criteria, or reduce the data set to a single aggregate value.
With that insight, these three methods are recognition — and implementation — that the reason you loop through an iterable often falls into one of these three functional categories:
- Map: Apply the same set of steps to each item, storing the result.
- Filter: Apply validation criteria, storing items that evaluate True.
- Reduce: Return a value that is passed from element to element.
What Makes Python Map/Filter/Reduce Different?
In Python, the three techniques exist as functions, rather than methods of the Array or String class. This means that instead of writing
my_array.map(function) you would write
The syntax between a lambda expression and arrow function is actually quite similar. Swap the
=> for a
: and make sure to use the keyword
lambda and the rest is almost identical.
const square = number => number * number;// Python Lambda Expression
square = lambda number: number * number
One key difference between arrow functions and lambda expressions is that arrow functions are able to expand into full-blown functions with multiple statements while lambda expressions are limited to a single expression that is returned. Thus, when using
reduce() if you need to perform multiple operations on each item, define your function first then include it.
result = number * number
return resultmap(inefficientSquare, my_list)
Replacing For Loops
All right, on to the good stuff. Here are three examples of common for loops that will be replaced by map, filter, and reduce. Our programming prompt: Calculate the sum of the squared odd numbers in a list.
First, the example with basic for loops. Note: This is purely for demonstration and could be improved even without map/filter/reduce.
numbers = [1,2,3,4,5,6]
odd_numbers = 
squared_odd_numbers = 
total = 0# filter for odd numbers
for number in numbers:
if number % 2 == 1:
odd_numbers.append(number)# square all odd numbers
for number in odd_numbers:
squared_odd_numbers.append(number * number)# calculate total
for number in squared_odd_numbers:
total += number# calculate average
Let’s convert each step to one of the functions:
from functools import reducenumbers = [1,2,3,4,5,6]odd_numbers = filter(lambda n: n % 2 == 1, numbers)squared_odd_numbers = map(lambda n: n * n, odd_numbers)total = reduce(lambda acc, n: acc + n, squared_odd_numbers)
There are a few important points of syntax to highlight.
filter()are natively available. However,
reduce()must be imported from the
functoolslibrary in Python 3+.
- The lambda expression is the first argument in all three functions while the iterable is the second argument
- The lambda expression for
reduce()requires two arguments: the accumulator (the value that is passed to each element) and the individual element itself.
Best wishes moving away from a flood of for loops. It’s important to remember that for loops do have a place in your code, but expanding the toolkit is never a bad thing.