[MUSIC] So you've seen many of the things that you can do with lists. In this lecture, however, we're going to look at some examples so you can see concretely different ways in which you can use lists. And most importantly, I'm going to show you iteration. Iteration is the operation on lists that allows you to step through the list element by element, and actually do something to each element if you'd like, all right. This is where lists really get their powers. So hopefully, by seeing this in action, you're going to have a better understanding of how this is operating, how you can use list in your programs. So let's get started. Okay, so here I am with a simple skeleton of a program here. We're going to get, take a list of numbers, and we're going to look at odd numbers in that list. Okay, so first thing. I've got my list of numbers and I'm going to print them out. Okay, we already know how that works. Great, I've got the list over here in the console. So now, let's try to count the number of odd numbers, okay. All right, so I take a list of numbers as input, and let's start a variable count at zero. Now, I want to iterate over the list, so I use for num in numbers, okay. This allows me to go through all of the elements in the list number, okay. And each element gets assigned to num one by one, okay? And so I can say, if num modular 2 == 1, okay that means it's odd, then let's increment the count. And at the end, let's return the count, okay? So, how do I check if it's odd? Well, I divide it by two basically. If I do num mod 2, I'm going to get zero or one, right? If I divide it by two and there's no remainder, I get zero. If I divide it by two and there is one as a remainder, I get one, right. And if there's a remainder, then it's odd. So if that happens, I increase the count by one, all right. And each time through this for loop, num is going to get the next element in the list. So I'm going to actually check each element in the list if it's odd and I'll increment the counter if it is, all right? So let's check in my list of numbers here. Let's print count_odd, and numbers, okay. See how many numbers are odd. There are seven odd numbers in my list, okay. Now, I can do a bunch of other things. Let's actually try and check if there are any odd numbers at all in the list, okay. So we start with a Boolean flag here, okay. And this is a common programming technique, where I have a Boolean variable that tells me if something has happened or not. So initially, I have not found any odd numbers so I set odd equal to false. Now, I iterate over the number's list. If I find an odd number, I set that flag to true. Okay, and now I can return odd, all right. So let's check that. See if there are any odd numbers. Print check_odd numbers, okay. Both of these are sort of useful techniques that you will see again and again in programming. Where I operate over a list and I increment a counter of some sort, or I iterate over a list and I check to find something in that list, okay. All right, now it's fun to count the odd numbers on the list. It's fun to check if there are any odd numbers in the list. Although I, hopefully you realized that if I can count the odd numbers in the list, I don't really need another function to check if there are any odd numbers in the list. In fact, if the count is greater than zero, I know that there are odd numbers in the list. Now, before I move on to this, doing something more interesting, I want to point something out. As soon as I find an odd number, do I have to actually keep looking in this check_odd function, okay. So if I'm going to do it this way, it's not really that much different or better than counting the number of odd numbers and seeing if there is more than zero, okay. But I can do better. What if this list were really, really, really long and the second number in the list were odd. Well, then I could stop, all right. So instead of using a flag here, what I could do, so ignore that, all right. Go through here and if I find an odd number, I return true. And if this loop finishes going through all of the elements in the list and doesn't return true, well I know there's not an odd number in the list. I can return false, all right. And you can see that it still works. I still find it's true, all right? Now, I want you to think about this. This return statement here is in the middle of the loop. What that means is, I don't finish. As soon as I get to a return statement in a function, the function ends and it returns a value, okay. So before, I had that flag, I just set it to true. And I might set it to true a whole bunch of times, that doesn't matter. And then at the end, after I've gone through the entire list, I return true or false. Here, I go through and as soon as I find an odd number I return true. If there are no odd numbers in the list, I'll go through them all, find out there is none, and return false. Notice that I have to go to through the whole list if they're all even, right? The only way that I'm going to know they're all even is if I check them all, okay. All right, now what about if I want to do something even more interesting. I want to remove all the odd numbers in the list, okay. So, the obvious thing to do here is to go for num in numbers, okay. If num mod two is one, then I want to do numbers that remove num, okay. And this is going to get rid of all the numbers in the list, all right? So let's, there are all the odd numbers in the list. So let's do that. Let's call remove_odd, odd numbers and let's print numbers again, okay. And let's see what happens here. All right, works great, right? Mm-hm, wait a minute, I see some 7s in there, okay. It did not get rid of all the odd numbers. Now what is wrong with my program? It looks fine to me, right. I went through each number in turn, for all num in numbers, so num is going to get each value in numbers. I checked if num mod two is one and if it is, I call the numbers removed on them, all right. Looks good, okay. But this does not work, and this is a very, very common error. You cannot change the list that you are iterating over. So while I'm iterating on numbers, I can't change it and expect everything to work okay. So what's happening is, things are getting removed. As I'm trying to go to the next element, I might skip elements, I might do elements twice, right, depending on how you change it, okay. So Python does not allow this. You have some unpredictable behavior if you ever actually do it. So, let's think about how I might actually solve this problem. Okay, so how can I deal with this problem? Well, a common way of handling the fact that I can't modify a list while I'm iterating over it, is to create another list, okay. So, let's try remove_odd 2 of numbers, okay. And now I'm going to create a new list called remove, and this is going to hold the indices of the elements that I want to remove. So for num in numbers, if num mod 2 equals 1, and remove.append numbers.index of num, okay. And when I'm done with that I want to go for index in remove, numbers.pop, index. Okay, this looks great. Let's make sure we're calling remove two down here, yes we are. All right, and let's run this. Okay. Well that didn't work. What is the problem here? Well, as I'm iterating over remove, I'm popping out indexes out of number. But each time I pop something, it shifts all the other elements to put to the left to fill the gap, okay. So the indices are no longer the correct indices, okay. So I'm not modifying remove here, I'm modifying number but it's not working very well. So, let's try instead to change this. Let's call it remove_odd3. We could copy here so I can remember what that looked like Okay, in remove_odd3, instead of putting the index, let's just put the number. Okay, and numbers.remove. Okay, I know they're going to be in there. It's not an index anymore so let's call it a num. I know they're going to be in there because I put them in there from numbers. going to remove them, okay. Let's call remove_odd3 and see what happens. Okay, finally. All right, this looks like it works, okay. I created a list of all the numbers that I wanted to remove in remove. Then I iterate over that list, and I actually removed them from my original list. Okay, great. I think actually in this case, I might have done better if I just created a new list, okay. This is kind of complicated here. Sometimes this works well, depending on how you want to handle the situation. But I think, here in this particular case, if instead I say newnums is an empty list for num in numbers, okay. If num % 2 is even, then newnums.append num and let's return newnums, okay. Now, Print, actually let's do it this way. Delete this stuff. Print remove_odd for numbers. Okay, and if I reset and run, you can see that I've also, now I have a new list that doesn't have any odd numbers in it. So it's actually done what I wanted it to do, okay. Now I want you to think about these things, and I actually want to show you one last thing, all right. And let's say remove_last_odd, okay. I want to get rid of the last odd number that I find, okay. So let's say, first we're going to have a flag has_odd, right, because I might not have an odd number in it, okay. Okay, and last_odd, let's just set that to zero for now because I haven't found one yet, right. So for num in numbers, okay, if num % 2 equal 1, I found an odd number. Let's say, has_odd = True. I set the flag so I know that I've now found it, last_odd = num, okay. Now, when I get out of this loop, if has_odd is false, then there's nothing to remove, okay. So I have, if has_odd, so if there's actually an odd number, I can say, numbers.remove(last_odd), okay. And this is great, right? So I go here, I print numbers. And I call remove_last_odd on numbers, print numbers again, and let's run this, okay. And it removed the last odd number, right? Mm-hm, no, that 7 is still there at the end. Now, given what we talked about in this lecture, I want you to look at that code, I want you to think about that code, and I want you to see if you can actually fix it, okay? All right, now we've seen a whole bunch of different ways that I can iterate over these list and I can modify the list, all right. But I just can't modify them while I'm iterating them. Okay, you saw several examples of how to iterate over a list in this lecture, right. You saw how to check if a list has something in it. You saw how to count things that are in the list. You saw how to create new lists or modify lists, based on some criterion, okay. These are all powerful ways in which you can use lists, all right. And the combination of understanding the different methods that lists have and being able to iterate over the list, gives you a powerful data type that allows you to do a lot of different things in your programs. So hopefully, at this point, you feel a little bit comfortable with lists, and you'll be able to use them to maximum effect.