Intermediate Python Intermediate Python

Practice: Comprehensions, Slicing, & zip Function

Check out a free preview of the full Intermediate Python course:
The "Practice: Comprehensions, Slicing, & zip Function" Lesson is part of the full, Intermediate Python course featured in this preview video. Here's what you'd learn in this lesson:

Nina walks through the practice where students manipulate data structures using comprehensions, slicing, and the zip Function.

Get Unlimited Access Now

Transcript from the "Practice: Comprehensions, Slicing, & zip Function" Lesson

[00:00:05]
>> Nina Zakharenko: For this second exercise, we're gonna practice our comprehensions. Our list comprehensions and more. We're also gonna take a closer look at slicing and use the zip function.
>> Nina Zakharenko: Okay, so we talked about all sorts of different types of comprehensions. Comprehension looks something like this. I can say, give me all the even numbers from 0 to 99 by looping through and saying for num, let me say for num in range of 100

[00:00:58]
>> Nina Zakharenko: And going back to the beginning, I know that I just want the number. I don't want anything special with it.
>> Nina Zakharenko: If I wanted to get just the even numbers, I would do a modulo check and say that if the num % 2 is 0, that's even.

[00:01:19] One important thing to remember here is that you have to use the equality operator to check that the value is explicitly 0. Otherwise, it's gonna be falsy. And you're gonna get the odd values instead. Okay, there we go. I'm gonna assign this to a variable.
>> Nina Zakharenko: And I'm gonna use something from this standard library, the random method.

[00:01:58] It’s gonna help me get a random number. In the REPL, you can type import random. But know that when you do imports Python files, you always wanna put your imports at top. And as an aside, there is a command in the command pallet call organize imports. Once you start making Python files with a lot of the imports, it'll just organize them in a really nice way for you.

[00:02:29]
>> Nina Zakharenko: So,
>> Nina Zakharenko: I want to make a dictionary where the key is the number and then the value is just a random number from 0 to 99. So to get a random number, I can say random.randint. And let's say I didn't remember what this method did or what the arguments were, what can I use to get me a little bit of guidance?

[00:03:00]
>> Audience: Help?
>> Nina Zakharenko: The help method, yeah. So I can pass this whole thing into help. And I'll say rand, a and b, return a random integer in the range of a and b, including both endpoints. Okay, so I'll call random.randint(0, 100) and call this multiple times, get a new value each time that's random.

[00:03:28] So for my dictionary, I'm gonna make a dictionary comprehension. And what's the difference in syntax between a dictionary comprehension and a set comprehension?
>> Audience: The colon.
>> Nina Zakharenko: The colon, right. So on the left side of the colon is my key. And on the right side, I'm gonna use this random.randint from 0 to 100.

[00:03:57] What am I looping over?
>> Audience: The list.
>> Nina Zakharenko: Right, my list, so I'm gonna say for num in my_list.
>> Nina Zakharenko: And taking a look at my_dict, there we go. Each value is a random number.
>> Nina Zakharenko: Let me look at the values that were generated. You can do that with my_dict.values().

[00:04:26] And it's likely that there are some duplicates here. Not entirely sure, right? The numbers are random. So if I wanted to quickly de-duplicate this data structure, there's two ways that I could do it. The first would be to pass it into a set.
>> Nina Zakharenko: Or I can use a set comprehension too.

[00:04:56] Let's say if I wanted to make some modifications before I de-duped it, that would be a good use for a set comprehension. So here I could just say, num for num,
>> Nina Zakharenko: In my_dict.values.
>> Nina Zakharenko: Whoops, I'm sorry about that, there we go. And that'll do the same thing.

[00:05:23] For slicing, I'm gonna make a new list with the numbers from 0 to 99. As we saw, I can do that in two ways. If I had the range from 0 to 100, I can pass this into list.
>> Nina Zakharenko: Or if I wanted to make some modifications to it, then at list comprehension would be a good way.

[00:05:48] I could just say, num for num in range(100). And my modifications would be here, but I'm just gonna show you this as an example. I'm gonna name this my_list. And I'm gonna take a slice of the list. In the REPL, it's easy to see the slicing as you go.

[00:06:12] So the first thing I wanna do is take a slice from the 30th value to the 69th one.
>> Nina Zakharenko: If I wanted to do the same slice but take every other value instead, what is the third parameter I can add here? Every or other?
>> Audience: [INAUDIBLE] 2.
>> Nina Zakharenko: That would be 2.

[00:06:39] So that would give me every other one.
>> Nina Zakharenko: If I had my list here and I wanted to get all the values in it but just in reverse, what is a shortcut using slicing?
>> Audience: Colon, colon..
>> Nina Zakharenko: ::-1.
>> Nina Zakharenko: From the Introduction to Python course, what's another way that we can reverse all of the values in a list?

[00:07:11]
>> Audience: .reverse.
>> Nina Zakharenko: .reverse, yeah. I can say my_list.reverse() # does the same thing.
>> Nina Zakharenko: What is the difference here? This didn't return anything, right?
>> Audience: Sorted in place.
>> Nina Zakharenko: Sorted in place. Well, this returns a copy.
>> Nina Zakharenko: Okay, I'm gonna .reverse my list one more time so that we end up with the same thing.

[00:07:47] If I wanted it to return a reverse copy of the list, what's one other way that I can do it?
>> Audience: Sorted with the reverse true.
>> Nina Zakharenko: Right.
>> Nina Zakharenko: So,
>> Nina Zakharenko: Sorry, that's not quite right. It will work on this list of numbers, but that's because they're all already in order.

[00:08:15] So just kind of to keep in mind that when we use that, .reverse and this syntax will return the list backwards. But if you use .sort or sorted and pass in the reverse flag, it's gonna do a descending sort. So hard to see with a list of numbers, but easier to see with other types of data structures.

[00:08:47] Okay, let's talk about zip. Yeah Nina, Max, Floyd, and we have Lloyd.
>> Nina Zakharenko: And they all have some scores in a game. Let's use random again here and ask for a random integer between 0 and 100. And I'm gonna loop through each name.
>> Nina Zakharenko: No, I'm losing. [LAUGH] Okay, so if I wanted to zip up these values, I can say, for name, score in zip(names, scores).

[00:09:35] And print out an f string that says, {name} got {scores} points.
>> Audience: You want score instead of scores.
>> Nina Zakharenko: Thank you.
>> Nina Zakharenko: Group pair programming is always the quickest way. Okay, there we go. What if I wanted a dictionary of these names to their scores? I can just pass that zip into the dict constructor and end up with that.

[00:10:22] Someone asked a really good question while they were doing the exercise, and so I wanted to review that very quickly so that we're all clear on it. So if I look at the zip of names and scores and get back something that looks like this, this is usually a hint that this type of object might be a what?

[00:10:40]
>> Audience: Generator.
>> Nina Zakharenko: Yeah, it might be a generator. And note, for these built-in types, if you make your own classes and you don't put in a string representation, you might also see something like this, but it's not a generator. You just didn't go through with putting a representation function in there.

[00:11:05] If I then assign this to a variable, so,
>> Nina Zakharenko: I'm gonna show you what happens when a generator is exhausted. I'm gonna say that my_zip is the zip of the names and the scores.
>> Nina Zakharenko: If I loop through this, and I'm just gonna say, for z in my_zip, print(z).

[00:11:39] And it went through each tuple in the list, printed it out.
>> Nina Zakharenko: We know that these generator expressions, they only know kinda their current value that they're returning. And they know just the next step in the future. They don't know anything about the past. And they can't see far ahead into the future, so,

[00:12:08]
>> Nina Zakharenko: If I try to do this again and say, for z in my_zip, print(z), what do you think I'll see?
>> Nina Zakharenko: Nothing, why is that? It's because-
>> Audience: Used it up as we go through?
>> Nina Zakharenko: Yeah, I've already used it up.
>> Nina Zakharenko: It's empty. It knew that the last step was, it finished the last step, and then it's gone.

[00:12:46] There's nothing more in it. So you can't reuse these generators. They're kind of a one-time use sort of thing.