 Hi, my name is Spasti Amato, and today I would like to show you how you can use list objects effectively in Python. Now for this tutorial, I will use Python 3.4 as you can see here, but all the tricks that I will show you are equally applicable to Python 2.7 or any other recent version of Python. Now to start with the basics, what is a list? Well, a list in Python is just a collection of elements, and elements can be anything. So you can have, for example, a list of numbers as you see here, or you can have a list of strings, as you can see here, list 2, and you can even have a list of other lists, as you can see here. So any kind of Python object can be put together into a list. A list is just a collection of arbitrary elements. A list has a particular order, so if we take a look at list 1, you see that the 0 comes before the 1, and the 1 comes before the 2, and lists can be changed, or as they say in Python, lists are mutable, which means that you can change one element from a list, for example, the 1 by another element, for example, the 3, right? So that's a list. A list is a collection of elements, and these elements can be anything. A list has a particular order, and a list can be changed. That's what a list is in Python. Now, let's say that we have a list like this, a list of names in this case, so a list of string objects. How can we access elements from this list? Well, that's very easy. Say that we want to access one element, and this is really elementary Python, you probably notice, you just say, for example, print names 0, and if I select this and I run it, you see that it will print the first name, Joe, to the terminal, right? So at position 0, we start counting at 0, so element 0 is Joe, and you get it from this list just using this square bracket notation. But you can do more. You can also select an entire range, or as you call it in Python, a slice from a list. Say, for example, that I type this print names 0 to 3, I select this, and I run it. You see it will print out Joe, Jean, and Marcel to the terminal, so it will print out from 0 to 1 and 2, and it will add position 3, right? So the 3 is the last, actually the first item that is no longer part of the range. Well, we can even make more complicated slices. Say, now basically what we're doing is we're making steps of 1, right? We're going from Joe at position 0 to Jean at position 1, to Marcel at position 2. Say that we want to make steps of 2, and we just add another column, and we say 2. So if I select this and I run it, you will see we go from Joe at position 0, and then we make a step of 2, and we go right to Marcel at position 2. So a slice can have a starting point 0, an end point 3 in this case, and a step size 2 in this case. Now, so far we've been counting from the start, right? So the first element is element 0, but we can also count from the back. We can say, for example, print names minus 1, and minus 1 is the last element. So we start counting from the back. So if I run this, you see it prints out Eric, which is the last item, right? So minus 1 is the last item, minus 2 is the second to last item, and so on, right? So if we want to count from the end of the list, we just do this with negative numbers. Now, we can even make negative slices in the following way. Say that we want to go print names from the last item to the 4 before last item, right? Item at position number 5. So this would be number 1, Marcel would be number 2, Jean would be number minus 3, Joe would be number minus 4, and number minus 5 would be like just before the list. And then we do this in steps of minus 1. So you see what's going on here? We start at the end of the list, and then with steps of minus 1, so backward steps of 1, we go all the way to the beginning of the list. So if I select this, and I run it, you will see that it prints out the list in reverse order. Now, what you will often see in Python is that people do this. They say names, and then they do column, column minus 1, and this magically reverses the list. If I run this, you see it does the same thing, prints out the list in reverse order. Now, this works because if we do not indicate the start and the end of a slice, right? So we don't do this here, we just put a column, and we just completely omit the start and the end of the slice. Python will automatically use the beginning and the end of the slice, which is why this statement here, minus 5, 2 from minus 1, 2 minus 5 in steps of minus 1, is identical to just saying take a slice with steps of minus 1, right? So column, column minus 1 is just a quick way, convenient way of inverting a list with a slice. But technically what it does is walk through the list with steps of minus 1. Okay, so now you know, essentially all there is to know about how you can access elements and slices from a list. Now, let's go to sorting, right? So because as I mentioned, lists have a particular order, right? In this case, Joe is the first, John is the second, Marcel and Eric. And often, of course, you will want to sort lists, right? And you can do this very simply. Say that we want to print a sorted version of this list, we just say print sorted names. If I select this and I run it, you see it works. It starts by Eric, which is the first because it starts with an E and we sort alphabetically my default. And then John, then Joe, and then Marcel. Now, if you do this, do it like this using the sorted function, you do not change the original list, right? So if I would print out the original function afterward and names, it would still not be sorted, right? So you could say sorted creates a new list that is a sorted variation of the original list, but it doesn't change the original list. If you do want to change the original list, you can do this with the dot sort function. You say names dot sort. And if I do this, I select this, you will see that actually the original list has changed and has become alphabetical, right? So there are basically two common ways of sorting a list using the sorted function, in which case you pass the list as an argument, or you call the dot sort function on a list, in which case you change the actual list itself. Okay, now, so that that that's the basic sorted way to sort lists in Python. But now let's say that we want to do something more complicated. We want to sort a list in a custom way, so not alphabetically, but using some kind of custom criteria. Say, for example, that we want to sort this list by the last letter of the name. Then we can do this using a trick, namely specifying a key to do the sorting. Now, if you specify a key like this using the key keyword, you have to indicate function. So let's say last letter. And then we have to define this function, def last letter, name, return, name, minus one, right? So we define a function that returns the last letter of name. And then we use this last letter to do the sorting by that's what happens here. Now, and if I select this, and I run it, you see that it works, right? We start again with Eric, because it starts the C comes first, then the E, then the L, and then the N. So this works. But we can do it a little bit more elegantly using a so called lambda function. Now, lambda function works like this. We can say names dot sort key is, I will just show it and then explain it key is lambda, name, name, minus one. Okay, now, these two things. Here's by explicitly defining a last letter function. And this way, using a lambda function, do exactly the same. What this lambda function is, basically, it is a way to specify in one line, a very simple function that has no name, but it takes it has no function name, but it takes a name as an argument. And it returns the last letter of this name. So that's what it does with a lambda statement, you can create a function just in a very quick way, just on one line, right? So you define a function that takes a name as an argument and returns the last letter of this name. And then we're going to use this to do the sorting. So if I select this, and I run it, you see that it works, right? And these lambda functions are very convenient, especially in combination with lists. And we will see it a few times more in this tutorial. Okay, so now you know the basic ways of sorting a list. Let's move on to a very convenient function, the map function. Now, to explain what map does, let's start with this very simple scenario in which we have the same list of names. And we want to create a new list in which which has the same names in it, but the first letter of each name is capitalized. Now, we can do this like this, right? We can create a new names list. Then we walk through all names in the list. Then we capitalize each name, and dot capitalize is just a built in function of strings that capitalizes the first letter of a string. And then we add this to our new names function. And then we print it out. Now, if I select this, and I run it, you will see that it works. Sorry, print name, select run, you see that it works, right? There we go. You see that it works, Joe, Jean, Marcel, Eric, right? So and you will see that the first letter is capitalized. But we can do this, we can do this in a more elegant way using the map function. What we can do, I will just type it and then explain how it works. We say new names is map. And then we specify a function that is applied to every element from the list. And to do this, we're going to use again a lambda function. Lambda, name, name, dot capitalize, comma names. Now, if I select this and I run it, you see that it does exactly the same thing, right? It prints out all the names with capitalized first letters. Now, what happens here is that basically, we have specified a function, again, a lambda function that accepts one name as an argument and returns that name with the first letter capitalized. Then we use the map function to apply this lambda function to every element from the names list. And we store the result in new names, right? So map is a very convenient function that applies another function to every element from a list. So it basically, it's a more elegant way to do what many people would do using a kind of for loop, as I showed you before. So that's what you can use map for. Now, let's move on to another function, the filter function, which is in a way quite comparable to map. So let's explain what the filter function does by considering the following scenario in which we again have a list of names. And what we want to do is from this list, we want to select only the names that start with the letter J. Now, so we create a new empty list. We walk through all the names in the original names list. If the name starts with the letter J, we append it to the new names list. And then we print it out, right? I fix this again. So now, and if I select this and I run it, you see that it works, right? It runs out only Joe and Jean, because those are the two names that we start with J. But we can do this in a way that's more elegant using the filter function, which, as the name suggests, is used to filter a list, right? And what we're essentially doing here is filtering this list. Now, filter works as follows. Let's say we remove all this. And we just say that new names is filter. And then as the first argument, we specify a function that should return true if an element should be included and return false if the element should not be included, right? So it's a function that determines what we're going to how we're going to filter the list. So we say lambda name, name dot starts starts with J comma names. Select this and I run it. You will see that it works. It again prints out Joe and Jean. So what happens here is basically we specify a function that accepts a name as an argument and returns true if the name starts with a J and falls if it doesn't start with a J. Now, this function is used to evaluate every name from the names list. And the filter function uses this to select only those names that start with a J and stores the result in this new filter, in this new list, right? So filter is a very convenient function that you can use to select a subset of elements from a list using some kind of criterion. And again, using a lambda function in combination with filter is very convenient, just like using a lambda function in combination with map was very convenient. Okay. Now, let's move on to the next next trick. And that's actually very, very cool trick. And it's called list comprehensions. And it's a bit it's a bit abstract. But if you get the hang of it, it's really very convenient. So let's to explain what what it does. Let's consider the following scenario, which is actually a combination of the two previous scenarios. So what we want is we want to create a new list based on the original names list in which all first letters are capitalized. But we only want to select those names that start with J. Now, then we can do this in the following way with the for loop, right? We can say new names is an empty list. We walk through all names. If a name starts with the letter J, we capitalize it. And we append it to the new names list. And then if we print it out, I select it and I run it. Oh, name, select run. You see that it works. We print out Joe and Jean, both with capitalized first letters. What we can do this in a in a more elegant way, using a list comprehension. And that works as follows. What we do is basically we remove this and we say, okay, we want to capitalize each name, capitalize each name. And what is name? Well, name is for name in names. And this is already a valid, a valid list comprehension. So basically we specify a for loop as part of this weird notation. And on each element of the for loop, we apply the to each element of the for loop, we apply the capitalized function. Now, if I select this and I run it, you see that it works, right? It capitalizes each, each first letter of the name. But then we can also specify an if statement. So we can say if name dot starts with j. If I select this and I run it, you will see it prints out only Joe and Jean and capitalizes the first letter. So a list comprehension is basically a clever way to walk through a list for name in names. Select only those elements that satisfy some criteria if name dot starts with j. And then apply some kind of operation to the elements that are selected. In this case, name dot capitalize. And you can do this with this particular notation that you see here. So you do it between square brackets, you indicate the operation, then for loop. And then if you want, this is optional, you specify an if statement. And list comprehensions are a very, very concise, very short way to work with lists. Okay. Okay, so let's move on to the next function, the zip function, which is really very convenient, really very convenient function. Now, let's say to explain what zip does, let's say that we have two lists, one list of names, and one list of associated birth years, right? So Joe is born in 1980, John's born in 1972, that's answer one. And what we want to do is print out for each name when that person was born. So we can do that again, as always, we can do it with the for loop, right? So we see how many names there are, which is four, then we create a range from that, right? So it would be a range from zero, one, two, and two, three, and including three. We loop through that range, and then we print out first we print out name, name zero, and birth year zero, then name one, and birth year one, et cetera. Now, if I select this, and I run it, you will see that it works. It says Joe was born in 1980, John born in 1972, et cetera. But it's quite ugly, right? Because we have this weird construction in which we have a length nested within a range, which is quite ugly. So we can actually do this in a better way using a zip function. And what we do is very simply we do the following. We say, instead of four i in range length names, we say four name comma, birth year in zip names comma, birth years, and we remove this, and then we print out name and birth year. It's called on here. Now, if I select this, and I run it, you will see that it does exactly the same thing. So basically what zip does is simply it creates a it zips together the names and the birth year list, and it returns first a tuple consisting of the first name and the first birth year, then tuple consisting of the second name and the second birth year, and so on. So zip is a very convenient function to zip together lists if you have separate lists of elements that are really associated by the position of the elements in the list, right, which is the case here, because the elements here are associated by their position in the list. So zip is really a very convenient function to use and remember. Okay, now let's move on to the final function, enumerate. Enumerate is again one of those functions that solves the problem that you see very, very often. Let's say that we have a list the same names as always, and what we want to do is we want to print out for each name the position of that name in the list. Now, we can do this as follows, right, we start with the counter variable i, which is zero, then we loop through every name, we print out the name n i, right, and then we increment i by one. I select this and I run it, you see that it works, it print out zeros, joe, one, et cetera. What we can do is better using the enumerate function, which goes like this. We simply say for i comma name in enumerate names, and then if I select this and I run it, you see it does the same thing, but it has saved us two lines. So basically what enumerate does, it returns a tuple of the position of each element and the element itself, right? So i would be the position of the element and name would be the element itself. So that's very, in a lot of cases, enumerate saves you from having to use kind of counter variables to keep track of where you are in a list. Okay, well, that's basically all I wanted to say. So what we have seen today is that a list is a collection of arbitrary elements that has a particular order and it is mutable, a list can be changed. You can slice through a list by, you can get elements from a list by number, either positive numbers starting from the beginning or negative numbers starting from the back. And you can get slices from a list using a start position and end position and a step size. You can sort lists using the sorted function or the dot sort function. And for custom sorting, you can use a, you can specify a sort key, which has to be a function. We've seen that there is a map function, which applies one particular function, which is usually a lambda function to each and every element from a list. We have seen that there is a filter function, which selects elements from a list based by the result from some kind of filtering function, which is usually also a lambda function. We have seen that you can use list comprehensions to apply an operation to every element from a list, optionally selecting only elements that satisfy some kind of criterion. We've seen that zip allows you to zip multiple lists together. And we've seen that enumerate allows you to walk through a list while at the same time getting the position of each element in that list. Okay. Thank you very much.