Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Reducing Lists and Lambdas

00:00 In the previous lesson, I showed you how to use the chain method from the itertools library to flatten a list of lists. In this lesson, I’ll show you how to use the reduce() function from the functools library to do the same.

00:13 If itertools contains functions to help you iterate, it seems to make sense that functools contains functions to help you function.

00:21 That sounds funny, but there’s actually a whole programming style known as functional programming where functions can be chained together to produce results.

00:29 Python isn’t a pure functional programming language, but it does have some features built in that allow you to write code this way. By having these features, it means you can choose the coding style that best suits the problem that you’re trying to solve.

00:43 Inside of functools is a function called reduce(). Reduce is an accumulator. It takes a function and an iterable. For each item in the iterable, it calls the function.

00:55 The result of that function is then called with the next item in the iterable and so on until the iterator is complete. An example will hopefully make that a little clearer.

01:07 This isn’t Python it’s a fake language I just made up where angle brackets denote a callable function. My fake function adds two values together. What reduce() does is call this function on the first two values of the iterable, in this case, adding them together, then calls it again with the result of that call and the next value in the iterable.

01:28 Let me walk through this. The first call sums the first two numbers in the iterable, giving me three.

01:35 The next call takes that three and adds the next value, which is five, giving me eight.

01:41 The accumulated eight gets added to the next value of nine, giving the final answer of, hold on, I have to take my socks off and use my toes, 17. Many programming languages have anonymous functions and some have them as a core concept that everything else gets built upon.

01:58 Python doesn’t go that far, but it does have anonymous functions called lambda expressions. These are lighter weight than regular functions and often get used in situations where you need to pass around a reference to a function like in functional programming.

02:13 The structure of a lambda uses the lambda keyword, an argument specifier, a colon, and then the calculation. This example is unity. It takes an argument named x and returns the same argument.

02:27 This next one is slightly more complicated returning five more than whatever is passed in.

02:32 Lambdas can have multiple arguments. You specify multiple arguments by listing them with a comma, and in this case, the end result is the sum of x and y.

02:42 These three examples are pretty simple, but think back to the previous slide. Reduce takes a function as an argument, so how do you perform that angle bracket thing?

02:50 In my made-up language in actual Python, well, you can use a lambda expression.

02:58 I’m in flatten.py so often it feels like home. This time I start out by importing reduce from functools and here is the reduction.

03:08 The function I’m giving reduce is a lambda expression that takes two arguments and adds them together. This might seem a little weird, but it really hearkens back to the idea of += you saw a few lessons back.

03:22 When you add two lists together, you get a new list comprised of the pieces of the summed lists. There isn’t any addition going on here, but instead the add operator on a list invokes the .extend() method. reduce iterates through nested.

03:37 First, it calls the lambda, adding together the first two rows, which produces a flattened list based on those two rows. Then each subsequent row gets accumulated into the result of the previous call, essentially chaining the rows together.

03:54 I’ll admit this is a little counterintuitive and when I first saw this code, I thought, what are they adding and expected it to somehow munge the contents.

04:02 But as the contents are lists themselves, what you’re doing isn’t adding, but using addition, which extends because that’s what happens when you add two lists together.

04:12 Let’s see this work.

04:23 Maybe not so intuitive, but it definitely does the job. This isn’t the approach I take, but if you’re used to functional programming languages, this might actually seem more natural to you.

04:36 For all the operations you might perform in Python, there are equivalent functions that you can call instead. These don’t get used often, but are handy when you’re playing with functional programming.

04:46 Instead of writing a lambda like I just did, you can pass in an operator function instead. For example, the mul() function multiplies two values, while sub() subtracts.

04:58 And even all the comparisons you might perform are there: less than, greater than, less than or equal, greater than or equal, and equal. There are three operator functions that could provide alternative things you could pass to reduce to do list flattening.

05:13 add() is the equivalent of the lambda. I just finished showing you, adding two values together. concat() is like add(), but for sequences, doing the same thing that add() does for lists, concatenating things together.

05:25 And then there’s a whole family of operators that begin with i, and the i stands for in-place. iconcat() is in-place concatenation, which essentially is += when dealing with lists.

05:38 I’ll leave it as a bit of homework for you to write several versions of the flatten that uses reduce by passing in operator functions instead of a lambda.

05:47 Remember, the first argument to reduce is a reference to a function. Don’t use the parentheses on the operator function itself. You’re not trying to call it, you want to pass it and have reduce call it for you.

06:00 Next up, I’ll abuse the fact that add means .extend() for lists even more.

Avatar image for toigopaul

toigopaul on May 14, 2024

Help please. I tried a few things for the “homework”. I’ve tried things like:

return list(reduce(add, nested))

return list(reduce(add(), nested))

And I generally get:

NameError: name ‘add’ is not defined

Avatar image for toigopaul

toigopaul on May 14, 2024

Doh! I figured it out. I had multiple mistakes. A peek in the Sample Code of the Supporting Material was all the help I needed.

Become a Member to join the conversation.