Getting Started With Python's map() Function
Here are resources and additional documentation about lambdas:
00:00
So, a basic call to Python’s map()
function takes the following form. It takes two positional arguments. The first one is a function and the second one is an iterable.
00:11
And as we saw in the introduction, the idea of using the map()
function is that you want to evaluate function
at every element of the iterable
. Now, the first positional argument function
can be any Python callable, such as built-in and user-defined functions, classes, methods, and lambda
functions. map()
returns an iterator that yields items of the original iterable
transformed by function()
.
00:40
Now, you can also apply map()
to functions that take on multiple positional arguments. So in this call to map()
, the first positional argument function
takes on N positional arguments.
00:54
That means that the iterator returned by map()
will first take the first element of each iterable and use those as arguments into the function()
, and so then that would yield the first item returned by the map iterator.
01:11 And then the next item that’s returned or yielded by the iterator is obtained by taking the second element of each of the iterables and evaluating the function, and so on.
01:23
So, it’s clear then that the number of iterables N that’s passed into the map()
function has to equal the number of positional arguments accepted by function()
.
01:34
Now, one of the nice features with the map()
function is that the length, or the number of values yielded by the iterables that are passed into map()
—that length doesn’t have to be the same for all.
01:45
And so what’s going to happen is that the number of values that are yielded by the iterator that’s returned by map()
is going to equal the smallest number of values that are yielded among the N iterables that are passed to map()
.
02:00
So map()
takes care of all the details about when one of the iterables is exhausted, then the entire iterator returned by map()
will exhaust.
02:12
Now, you’re probably thinking to yourself “Mm, the result of map()
, I can probably just get what I need using a good old-fashioned for
loop.
02:19
So why should I use map()
then?” Well, let me give you a few reasons. Using map()
abstracts the details of iteration, resulting in a more functional approach to programming.
02:32
Now, I think for you to fully understand this statement, you just have to start using map()
. I’m not completely advocating that you abandon for
loops and list comprehensions, but you’ll see that every now and then your main problem is just to simply map a function to an iterable, and just simply writing that using the map()
function feels a lot more natural than just having to write out the details of an iteration. Now, a technical reason why you may want to use the map()
function is that it’s written in C and is therefore highly optimized.
03:04
The internal loop used in the map()
function can be more efficient than just the regular Python for
loop. Another technical reason why you may want to use the map()
function is that it returns an iterator, and so items are processed on demand, resulting in more efficient memory usage.
03:22
Another reason why you may want to use the map()
function is that when you have multiple iterables, it may be clearer to use the map()
function than using an equivalent list comprehension and the zip()
function.
03:34
We’ll make this comparison in a later lesson so that you can see for yourself whether in some cases it is maybe a little bit more readable to use the map()
function over, say, a list comprehension with the zip()
function.
03:47 All right, let’s jump into the code.
03:50
Let’s start by taking a look at the help()
documentation for the map()
function, so go ahead and type help(map)
.
04:00
As we saw, the map()
function takes in a positional argument func
, which is going to be a function, and then a certain number of iterables, and the number of iterables is going to equal the number of positional arguments taken by the function func()
.
04:17
The map()
function is going to return a map
object, which is an iterator, and the iterator will yield the values of the function evaluated at the iterables.
04:30
The iterator returned by the map()
function will stop when the shortest iterable in the call to the map()
function is exhausted. All right, let’s take a look at some examples.
04:44
Let’s start off with a very simple example, just so that you can see how the map()
function works. Let’s create a list of numbers and we’ll call the list numbers
, and the list is simply just going to contain, say, the numbers from 1
through 5
.
05:00
And what you want to do is simply square each of the numbers in the numbers
list, and then either save the information in an iterator or maybe just a list. So go ahead and define a function, we’ll call it square()
. And of course maybe in your application, you have a much more complicated function, but this will do for this simple example.
05:21
The function is just going to return x
squared, or x
to the power of 2
. Now let’s call map()
with the square
function as the first positional argument and the numbers
list as the only iterator, because square()
only takes in one argument.
05:41
Let’s save that in a variable, say sq_nums
, so “square nums”. All right, let’s take a look at the type of sq_nums
.
05:53
We get map
, and as we saw in the help()
documentation, map()
returns a map
object. Now, we can do several things with this sq_nums
. If we need it for, say, a for
loop, then we can just use it as if it’s any other iterator. For example, we could just print the values obtained or yielded by this iterator.
06:16
So, let’s go ahead and do that. for num in sq_nums:
let’s just print the value of num
. And there we go. We get each of those numbers in the numbers
list squared.
06:32
1
squared is 1
, 2
squared is 4
, and so on.
06:38 All right, let’s clear that up,
06:41
and let’s run that exact same for
loop again.
06:45
So for num in sq_nums:
print the value of num
. And in this case, nothing happens or nothing’s printed. If you’re not familiar with iterators, an iterator—which is what sq_nums
is—returns a value on demand and once all of the values that are yielded by the iterator are exhausted, then nothing else is returned and internally there is a StopIteration
error that happens in the for
loop, and it’s taken care of by Python and so we don’t see any type of error message—we just simply see nothing printed to the screen.
07:25
So, that’s just something to keep in mind. If you wanted to, say, keep the values of sq_nums
around, you could, say, create a list based on the sq_nums
iterator.
07:37 So, let’s go ahead and try that just so you can see it.
07:41
Let’s call it again sq_nums
, and we’ll call the map()
function, and at the same time, we’ll create a list
from the iterator returned by map()
.
07:54
And then now, sq_nums
is just a good old-fashioned list. And if we run that same for
loop again, of course, we get the same print statements, and of course sq_nums
is still a good old list. Again, that’s just something to keep in mind: The map()
function returns a iterator object.
08:16
And if all you need that iterator object is, say, for one for
loop and that’s all you need it for, then that’s probably what you’ll want to do, especially if it’s a iterator that yields a lot of values.
08:29
You don’t want to store a large list in memory if all you’re going to need it for is, say, one iteration or one for
loop, for example. You’re better off creating an iterator, and the map()
function does that for you.
08:43
The first positional argument to the map()
function—it can be any callable. So it could, for example, be a lambda
function. Now, the square()
function that you defined—it’s a fairly small function, it only takes one line of code, so that’s a pretty good candidate for a lambda
function. So we could, instead, if we were to go ahead and use a lambda
function, we would simply write map()
and then lambda x
and then just simply return x
squared. And we’ll use the same iterator of course.
09:17
If you’re not familiar with lambda
functions, there’ll be some more information in the notes that accompany this lesson. Let’s run that again. This is essentially the same thing, except this time we are passing in a lambda
function, which is a anonymous function. It has no name, it’s just simply defined for the sole purpose of being passed in as a argument to this map()
call. So, if we run that same for
loop again, we’re going to get the exact same result. There we’re just simply printing the numbers in the sq_nums
iterator.
09:52 So, to end this lesson, let’s do an example where we have some data and it’s split up into two lists, and the two lists represent the x- and y-coordinates of some point in 2D space.
10:06 What we want to do is simply compute the distance of the points specified by the x and y lists to the origin. So, suppose we have a list, say, of x-coordinates.
10:19
This will be -3.8
, 2.2
, 4.5
, and let’s just say 0.9
.
10:28
And then we have a list of y-coordinates, and this is going to be 1.2
, -0.5
, and so on. Now, I don’t know if you remember this from, say, your math classes in grade school, but if you want to know the length or the distance from a point in 2D space to the origin, the formula is square root of the point x—or, the x-coordinate squared plus y squared.
10:59 And so that is the function that we want to evaluate for each tuple obtained by taking the x- and the y-coordinates one at a time. Let’s go ahead and define this function.
11:13
We’re going to need the square root function from the math
module, so we’ll say from math
, let’s import the sqrt
(square root) function.
11:22
And then, you know what? Why don’t we just do a lambda
function inside the map()
call? What we want to do is we want to map the function that takes two positional arguments—these are going to be x- and y-coordinates—and it’s just going to return the square root of the sum of x
squared plus y
squared.
11:43
And we’re going to get those x- and y-coordinates from the x_coords
list and from the y_coords
list.
11:53
Let’s save that in, say, a variable called distances
, so we’ll add the s
there. And that’s it! What’s going to happen here is the iterator obtained by the map object will one at a time first take an x-coordinate and a y-coordinate and evaluate this function that takes two positional arguments, and will return this value for the first x
and the first y
.
12:19
So that’ll be the first value yielded by the map iterator—the iterator returned by map()
. And then the next value is going to be obtained by taking the second x-coordinate and the second y-coordinate, evaluating this function—this lambda
function—and then yielding that value.
12:37
So, let’s just quickly verify this. If we were to go square root of -3.8
squared plus 1.2
squared, then we’ll get 3.98
.
12:51
If we instead use the second x-coordinate and the second y-coordinate, then we should be getting from the iterator 2.25
.
13:04
Now let’s compare this with the values that are going to be yielded by the distances
iterator. So for d in distances:
go ahead and just print these values that are yielded by the distances
iterator. And as we saw, the first one—3.98
, the second is 2.25
, and the other two are given below. Now, let me show you just one last thing. If, for example, the x-coordinates list—let’s say actually it only had three x-coordinates and the y-coordinates had the same number as before, so in this case four. Then if we run the exact same code, so distances
, and we go ahead and print all of the values that are yielded by the distances
iterator, we’re only going to get three, and that’s because the iterator returned by map()
will yield as many values as the shortest iterable that’s passed into it.
14:06
So, this is a nice feature of the map()
function. It’s not going to give you an error, it’s not going to raise an error. It’s just simply going to iterate until it can’t and that’s going to be determined by which iterable passed into the function has the shortest length. All right!
14:21
This ends the basics on the map()
function. In the next couple of lessons, we’re going to be doing some more examples of using the map()
function, and sort of part of that is just to get you thinking about when you would want to use the map()
function and if it’s something that you want to do. And, you know, the more you try it, you’ll see that maybe the map()
function is something that you may want to try every now and then instead of, say, using a for
loop or even a list comprehension. We’ll talk about that later, also, in a future lesson.
Become a Member to join the conversation.