Mutability8:35 with Craig Dennis
Lists are mutable. You should be careful when passing them around or using them in loops. Let's explore why!
Slicing allows you to specify a range of elements from within a list. We will go over them in great detail in a bit. Here's a sneak peek (search for slicing).
Here's the solution using slices
def display_wishlist(display_name, wishes): print("====> Suggested gift:", wishes, "<=====") # Return a slice of the list from the 2nd element on... for wish in wishes[1:]: print("* " + wish) print()
All right, so we wanna come up with a handy function that 0:00 will allow us to display each wish list in a standard sort of fashion. 0:03 This is, as you know, a wonderful place to use a function. 0:07 So we want to display our heading, just like we did here like we say this, books. 0:11 And we also wanna display our list so we're gonna loop through list. 0:16 So we got this, right? 0:20 Let's make a new function. 0:22 So the function will look like, let's see, 0:23 we're gonna define the new function called display wish list. 0:26 And first we want to know what that heading is. 0:32 Let's call that display_name. 0:35 So that'll be books or video games. 0:37 And then the items that we want. 0:40 So we'll just pass in wishes cuz it's a wish whether it's a book or 0:42 it's a video game list. 0:46 This is the list of there that we're gonna pass it. 0:47 Awesome. 0:50 So first we'll just print out that header. 0:51 So we''ll say display_name and 0:53 we'll make that a colon. 0:58 There we go You know what, let's go ahead, let's do this suggested gift thing. 1:01 Let's go ahead and put this as part of our function. 1:07 Cause we'll suggest a gift from each one of them. 1:10 So, hm, you know what I was just thinking? 1:14 If we show a suggested gift from the list, 1:16 we shouldn't show it in the other part, right? 1:19 So I guess what we want to do is we just wanna pop that first one off, right? 1:22 I mean, what could go wrong? 1:26 So we'll say suggested_gift equals wishes.pop. 1:28 And we'll get the first one right? 1:34 So we want pop zero. 1:36 Okay, so let's make this stand out a little bit. 1:39 We'll say print, we'll add some arrows here at the front. 1:41 Let's really stand out and we'll print out that suggested_gift. 1:45 And we're removed that from the list. 1:51 So we can probably just do what we did before. 1:54 So we just wanna loop through each of the wishes. 1:56 So we can say, for wish in wishes and we will print. 1:59 Let's see so we used the star before for bullet, plus wish, there we go, 2:05 and then at the very end let's just add a blank print here 2:10 after the display wish list, so that will keep things separate. 2:15 Cool, so now we should be able to just call that function. 2:19 So we'll say display_wishlist and 2:23 we will call that for the display name is books. 2:27 And there that wish, the list of wishes we have that's called books. 2:33 And let's do it for video games. 2:37 So I can just copy this. 2:39 And instead of books, 2:41 we have video games. 2:45 Awesom, that feel pretty clean, right? 2:51 Let's git rid of these other things Here. 2:52 There you go. 3:00 Yeah nice and clean. 3:00 So we've got the two lists, 3:03 we have a function, we're gonna call it let's see what it looks like. 3:04 So we'll say python Awesome, looks like we go it. 3:07 I'm gonna scroll this up a little bit and run that again. 3:16 Sometimes the scrolling gets a little wacky here. 3:18 Cool, so we've pulled one off and we pulled the second one off. 3:21 And it looks right, looks good, right? 3:24 There's a little bug in our program though. 3:29 Let's take a look. 3:31 Do you see what that bug is? 3:32 Here, this'll really demonstrate it. 3:34 Let's do this, I'm gonna go ahead, I'm gonna call this again one more time. 3:36 That's weird. 3:45 The second time through, it's a little bit shorter and it's a different suggestion. 3:46 That's because we're changing the list with that pop command. 3:50 This pop command here is actually changing this list. 3:55 Now, I made that happen on purpose to really highlight 4:00 the caution that you should take when dealing with mutable objects. 4:03 So let's think about how a user of this function might feel. 4:06 They pass their list in here to get a function called display wishlist and 4:11 I'm pretty sure that they aren't gonna expect their list to get an an item 4:15 removed from it. 4:18 That's gonna come as a shock. 4:19 So remember, these parameters can be thought of like applying the label, 4:21 display name equals books and wishes equals books. 4:25 So we've applied a label to that object that was passed in. 4:29 Now, the label only lasts while the function is running and then it's removed. 4:32 But during that function execution, the label, 4:35 wishes, it's referring to the same object. 4:38 Now in this case, it was the video games list. 4:41 That's why when we call pop, it changes the object because it's the same object. 4:43 So there are better ways to do this. 4:48 One rule to follow is to not modify someone else's objects 4:50 unless you are explicit about it in your method name. 4:54 If you find yourself needing to change a list, like we did here just for 4:57 display purposes, you can use the copy method. 5:01 The copy method on lists allows you to make a copy of the list and 5:04 this leaves the previous one intact. 5:09 So let's go ahead and do that. 5:11 So I'm going to make a new copy of the list when we come in here and 5:13 I'm gonna call it items. 5:18 So items equals wishes.copy. 5:19 Not.copy and then instead of wishes here, I'm gonna say items. 5:23 And then we can say for item and 5:30 items, item. 5:34 So items is now a completely unrelated copy of wishes. 5:40 Now, I can change items all I want and it won't change this, just a copy. 5:44 So here watch, we'll run it again and you'll see both of them. 5:47 It stayed the same each time. 5:51 It didn't change that master video games list. 5:52 Now I should point out that you could actually solve this problem that we're 5:55 having here by not removing the element from the list at all. 5:58 And only iterating through the lists starting at the second element. 6:01 You could use what is known as a slice. 6:04 We'll get to that here in a bit, and check the teacher's notes for a sneak peek. 6:07 Another thing that I want you to be careful of is loops, and mutability. 6:10 So let's pop open a repel really quick. 6:15 Let's pop open, we'll say python 6:17 Let's take an example from one of those video games I was playing. 6:24 Let's use Zelda. 6:27 It's an adventure game, and you collect items, and 6:28 you keep them in your inventory. 6:30 So a typical inventory might look something like this. 6:32 So we have inventory, do a list and you might have a shield, 6:34 definitely have apples that's how you go ahead and eat things. 6:40 And then you have a sword, maybe you'll have a bow like for a bow and arrow, 6:43 a boomerang. 6:47 All right, basic inventory from an adventure game, right? 6:49 So one thing that we haven't looked at yet 6:54 is that you can remove an element from a list by value. 6:56 So you could say inventory. 7:00 And there is a method called remove and 7:04 let's say that we wanted to get rid of that apple. 7:06 So we're gonna remove the apple from our inventory and 7:08 now if you look at inventory, you'll see that it's gone. 7:11 A common problem that happens is that you mutate the list 7:15 while you're looping over it. 7:19 Like for instance, 7:21 let's say that you wanted to drop everything from your inventory. 7:22 You might think that you could do something like this, for item 7:25 in inventory, so we're just gonna loop though every single one of these items. 7:28 And, we'll say, inventory.remove, and we are going to remove that item. 7:32 That seems like it make sense, right? 7:39 But we were looping over it, so what happens is you get this weird 7:42 unexpected result, you still got a sword and a boomerang left. 7:46 So again, this is where copy saves the day. 7:50 You just loop over a copy of the array, like so. 7:52 Let's do this. So let's come up here. 7:55 Let's reset our inventory. 7:57 Here we go and for an inventory.copy, so we'll loop through each one of those and 7:59 then we'll choose, I'm using the up arrow here. 8:04 We'll remove from the master list. 8:08 So this will create a new list, we're not gonna assign it to a variable, 8:11 it's just gonna create a new one and it's gonna loop through that. 8:14 But we're gonna remove from the actual inventory list. 8:16 Now if we take a look, bam. 8:20 So just remember to be extra thoughtful when dealing with mutable objects. 8:23 After a quick break let's head back and I wanna show off some pretty great string 8:28 methods that are gonna help dealing with iterables like our list. 8:32
You need to sign up for Treehouse in order to download course files.Sign up