Practical Guide to Python List Comprehensions
Transcript from the "List Comprehensions" Lesson
>> We're gonna cover some advanced looping techniques that you might see like list comprehensions, how to convert between different types in Python, and how to work with files. So, list comprehensions are one of the more unique features of Python. And they're so popular that other languages have also started implementing list comprehensions as well.
[00:00:29] List comprehensions allow you to take what would normally be quite a lot of code that is actually pretty common while you're programming. Which is going through a list of items, having a list of results, and then appending to your results as you go through a list. So let's say that we wanted to take a list of names and return a list of the length of those names.
[00:00:59] And let's see what this would look like in a Python ripple. Let's do this in a new file. And I'm gonna save this as list comprehensions or list_commstop_ un, gonna go ahead and exit my repple and then run this file in the terminal. So I have a list here 4, 3, 4, 5 that relates to the length of each of these strings in the list.
[00:01:37] A list comprehension is going to let us do the same thing in one line pretty simply and easily. So here I'm going to print before followed by my list. [SOUND] And then, I'm going to write my list comprehension. So a list comprehension, I find it easiest to write kind of in reverse order.
[00:02:05] So I'm gonna start with the square brackets because I know that I want a list comprehension and square brackets are the syntax for lists. And then, I'm gonna type in what I'm looping over. So I'm gonna type in for name in names. Once I do that, I'm gonna move my cursor all the way to the left, [SOUND] to just after the opening square bracket.
[00:02:34] This is where I type in what result I want from looping over this set, or sorry, looping over these values. In this case, I want the length of names and that is a list comprehension, it replaces all of this. And now, I can print out after and run this and get the same thing.
[00:03:05] So I can assign it to a variable as well. And get the same result. I think this is pretty clean and readable and understandable. It is one of the things that folks who are new to Python tend to trip over quite a bit. And the best way to get over that hump is to just practice as much as possible.
[00:03:34] So typing in these exercises and getting that muscle memory and I find that trick of writing my list comprehensions in reverse really helps me remember. Okay, I need the square brackets because it's a list. I need to figure out what I'm looping over. And then, I need to figure out what do I want to extract.
[00:03:56] In this case, it's the length of the names. We can also have conditional statements in these list comprehensions. If we want to add a condition, we move our cursor all the way to the right-hand side, and that's where our condition goes. The condition is optional. And here you can type if, and an expression that either evaluates to true or false.
[00:04:26] When the expression is true, that value on the left-hand side will end up in the list comprehension, if that expression is false, it will not. So if I want to only get the, let's say the names that have even numbers of characters, I can say, remove this and say what I actually want is the name itself.
[00:04:54] And then, have a condition that says, if the length of the name modular 2 means is the length of the name even equal to 0, then put it in my_list. So now, when I run this, I will only see the names that have an even number of characters.
[00:05:17] If I flip this condition and say not equals, and run this, then I will get the other two names, the ones that had the odd numbers of characters. There are ways of moving between different types in Python. One is split. So if you have a string that is separated by commas, and you want to extract those values, you can use split.
[00:05:47] So going back to the repple, if I have a name string that looks something like this. You might see something like this in a CSV file, if you ever worked with those. If you want to get a list of names out of this string, you can call the .split method on it and pass in the token that you want to split on.
[00:06:21] If you have spaces in between those names, then you would need to pass in a token that is a comma and a space as well. So, this is one very quick and easy way of moving between a string and a list. If you then wanted to save these values in a CSV file.
[00:06:45] So in this case, I have not modified my name string. Remember, strings are immutable. So let's say I call this a names list. And I said name_strings.split on common. Now, I have a list If I wanted to get that back into a string, I can call the .join method on a string.
[00:07:13] In this case, it's gonna look a little funky. I'm gonna use space and then a dash and a space, and I'm gonna say .join. With my names list, and that's going to return a string that has this delimiter. You can also use this string joining with a list comprehension as well.
[00:07:42] So let's say that, I wanted to multiply each number in a list by 2. I could use a list comprehension for that and say for num in my_nums, and move my cursor all the way to the left side and say num * 2. That's going to be a list comprehension.
[00:08:17] I can call .join with this list comprehension, sorry, that did not copy right. I can call .join with this list comprehension here, and it will accomplish the same thing. Oops, sorry, I need to convert this into a string. Yep. So moving between types in Python is really quite simple.
[00:08:54] And if any of you have done any coding challenges like the advent of code calendar, you'll find that a lot of programmers who do that will reach for Python. Because moving between types is so simple and straightforward, and that's not necessarily the case in other programming languages. There are other kinds of comprehensions, like dictionary comprehensions, set comprehensions.
[00:09:22] I'm not going to talk about those during this course. There is a chapter available in the course website that you can read on your own, and there is practice available as well. What I do want to chat about though is generators. Generator expressions are, well, we've already seen some of those generator expressions.
[00:09:47] Like when we tried to call range, we didn't just get back a full list of all the numbers that range generated, instead we got back a different kind of function. So a generator is a more advanced concept. It's like an object that you're able to iterate over like a list.
[00:10:07] But unlike a list, a generator only knows about where it is now, and how to get the next value. And it does that on demand without generating that list of values all at once. So a generator comprehension does look a lot like a list comprehension, except it uses a single pair of parentheses instead of brackets.
[00:10:30] So here's a list comprehension where we are generating squares. For every number under 10 if that number is even, I could change this to a generator comprehension by changing these square brackets to parentheses. If I check the type of my list comprehension, sorry, I'm gonna call this my generator comprehension.
[00:11:04] If I check the tape of my generator comprehension, we'll see that it is a generator and if I try to look at it, it's going to come back with that. If I wanted to see what was in this generator, I could call list on it. But generally, when you are using a generator, you don't have a need to have all of those numbers or values or whatever in memory all at once.
[00:11:29] Instead, you probably want to loop through them and do something with them. So I can loop over every item in this generator comprehension. And print it out. And I can do that just like I would with a list, that syntax is seamless. The thing about generators though, is that once you use the generator, again it doesn't have any state.
[00:11:57] It's not stored in memory. So once you loop over all these items, the generator is exhausted. It doesn't know how to get back to whatever state it was in beforehand. So if I try to loop over this again, I'm not going to get anything back. I've used up my generator and if I want to use it again, I have to recreate it and start from scratch.
[00:12:25] So as Python has migrated to Python 3, a lot more of these internal structures have moved over to be generators or generator-like. And even though this is a more advanced concept, it's really important to know about because of those optimizations that have happened over the years.