# Lists in Python This notes covers the essentials of a set for IB Diploma. In the previous syllabus this was covered with Arrays. Lists and arrays are not the same but they have some similarities. ## One variable, multiple values We have covered already that we have variables, and we're used that when we have one variable, we have one value for example: ```python= x=5 y=6 potato="tomato" ``` But sometimes we want to have **more than one value in a variable** and for that we're going to use what is called, in an abstract way, _collections_. They allow to have more than one value in just one variable, fancy, right? In python we have several ways to work with them, let's name a few of them and some characteristics and differences. | Type| Set |Tuple | List | Diccionary | |--- |--- |--- | --- | --- | | Iterable | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | Duplicate values? |:x: |:white_check_mark: | :white_check_mark: |:x: | | Ordered? | :x: | :white_check_mark: |:white_check_mark: |:white_check_mark: ^1^ | Changeable? | :x:^2^ | :x: | :white_check_mark: |:white_check_mark: | Use keys?| :x: | :x: | :x: |:white_check_mark: | Syntax| `{ , }` |`( , )` |`[ , ]` | `{ : , : }` | Example| `{a,b,c,d}` |`(a,b,c,d)` |`[a,b,c,d]` | `{a:valueA,b:valueB}` | ```! 1: In Python dictionaries are ordered since python 3.7, before they were unordered. 2: What you cannot changes are the _items_ in the set, but you can add or delete elements to the set. ``` Now back to lists ## Why lists Even if all of these types are interesting, we're going to focus on lists because strings are sequences and there is another common type that is also consider a sequence: Strings (str in Python) That means that we can apply a lot of what we know to both (yay), even if there are some differences (not yay) ## Creation, genesis of a list We can create in python a list in different ways: 1) We can just say create an empty list `a= []` with the square brackets. Later we can add the elements in the list 2) We can fill those elements directly separating them between comas `myList = ["carrot", "letucce", "cabbage"]` or `superDuperList = [5, 3, 0, 10, 5]` 3) We can use a special function called **constructor** list() empty or with a parameter and it's going to create a list with that. For example `x = list()` is going to create an empty list and `numbers = list(range(10))` (range is another function that we didn't cover, for now, if you don't know it, it's ok it's just a function that retrieves something that can be converted into a list) 4) We can use list comprenhension that is put into brackets something that can be converted into a list. It's a bit advance for now but has the shape of this ` myCoolList =[x for x in iterable]` but we haven't covered loops yet! :::info Lists in python can have several types inside of them, you can have a list with booleans, string, numbers, complex types. This is not common in other programming (specially if they are statically typed). ::: So let's create a simple list! ### Exercise. Simple lists :::info **Naming convention**, even if in the exam we're not going to have this, is useful for writing variables that are lists (or other types of collections) names that are in **plural** like `grades` or `students` or `names` so we can have a hint that they are a type of collection ::: Create a list of elements of the periodic table (4 of them). These elements are strings. ```python! elements = ["Hidrogen", "Helium", "Lithium", "Berylium"] ``` Create a list of your five favourite numbers: ```python favs = [6, 7, 16, 63, 32] ``` Create a list of how many books have you read this year: ```python booksRead = [0, 5, 4, 4, 4] ``` :::info Notice that here we have duplicate values and it's ok! ::: ## Indexes and accesses Ok, so the idea is that we may have different values in our list, like `["apple", "car", "potato"]` but we need a way to access those values. For that, since lists are **ordered** we can retrieve the first, the second or the third element. Continuing with the favourite numbers ```python favs = [6, 7, 16, 63, 32] ``` How can we access to the 3rd favourite number? We use the brackets and the NUMBER of the index. Remember that they start with 0 so the index of the 3rd element will be 2. ```python print(favs[2]) ``` ### Special index accessing to create sublists In python (this is uncommon in other programming languages) you can create sub-list (so slices of the original list) using `:` in the brackets of the original one. ```python print(favs[3]) ``` This will return the 4th element (63) But if I write ```python print(favs[1:3]) ``` This will create a sublist from the second element (index 1) to the 4th (index 3) **not included**. In this case it will be `[7, 16]` ```python print(favs[:3]) ``` This will create a sublist from the first element to the the fourth (index 3) **not included**. In this case it will be `[6,7,16]`. ```python print(favs[3:]) ``` This will create a sublist from the fourth (index 3) included until the end of the list. In this case it will be `[63, 32]`. ### Negative indexes Python also has another implementation of indexes that allows the developer to access the last element using -1. In other programming languages this would en in an indexOutOfBounds error. So, if using negative indexes the first element would be - (size of the list). For example to access the first element of this list we can use several solutions ```python= b = ["OwO",5,5,7,5] print(b[0]) print(b[-5]) print(b[-len(b)]) ``` This will print 3 times "OwO" ### Deviation range() function Range is a function that in python we're going to use a lot and is going to return us an iterable (not exactly a set). If we send to range a number, is going to create an iterable from 0 to that number not including going 1 by one. So if I write this: ```python= y =list(range(10)) print(y) ``` It will print `[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]` If we send 2 numbers, it's going to create an iterable from the first to the second not included. So if we write this ```python= y =list(range(1,5)) print(y) ``` It will print `[1, 2, 3, 4]` If we send 3 numbers, the last one will be the 'step'. It's going to go from the first number until the second (not included) adding the 3rd number ```python= y =list(range(1,5,2)) print(y) ``` It will print `[1, 3]` :::info **Breaking a bit** If you try to do something weird, weird things may happen. ```python= y =list(range(1,5,2,3)) print(y) ``` This gives you an error because range can only have 3 arguments. ```python= y =list(range(1,5,-2)) print(y) ``` This is not going to give you an error, just an empty list. ```python= y =list(range(1,-10,-2)) print(y) ``` This will work and it will print `[1, -1, -3, -5, -7, -9]` ::: ## Common simple methods ### Length of an array: len() Len is a function that we can send our list and it's going to return a number that is the size of the array. It's very useful and common ```python!= b = ["OwO",5,5,7,5] print(len(b)) ``` One of the main uses of this is to **traverse an array** that we will cover it later using the indexes. ### append() ```python!= print(a) a.append(3) a.append(2) a.append(3) print(a) ``` https://www.w3schools.com/python/ref_list_append.asp ### insert() Is the same as append but instead of the end we need to specify FIRST the index of the list where our new element is going to be ```python!= print("Hello, World!") a = [] print(a) a.append(3) a.append(2) a.insert(1, "potato") print(a) ``` This will print `Hello, World! [] [3, 'potato', 2]` https://www.w3schools.com/python/ref_list_insert.asp ### remove() This is going to ask for a **VALUE** and it's going to remove the first element with that value. ```python= a = [7,5,5,7,5] a.remove(5) print(a) ``` This will print `[7,5,7,5]` https://www.w3schools.com/python/ref_list_remove.asp ### pop () This is going to ask for an **INDEX** and it's going to remove the first element with that value. ```python= a = [7,5,5,7,5] a.pop(3) print(a) ``` This will print `[7,5,5,5]` Here we can also use negative indexes ```python= a = [7,5,5,7,5] a.pop(-1) print(a) ``` This will print `[7,5,5,7]` https://www.w3schools.com/python/ref_list_pop.asp ### index() This is going to return the index of the first value that we input https://www.w3schools.com/python/python_lists_methods.asp ### Others Here you have other commonly used list methods. https://www.w3schools.com/python/python_lists_methods.asp :::warning :warning: In the exam they are going to ask you to **implement** algorithms of sorting so probably in the exam you're not going to be able to use "count()", "sort()" or "reverse()". This will be explicit in the exam. In the Internal you can use them freely. ::: ## Traversing a list For this we need to explain the for loop in python. ```python= myList= ["Pipo", "Pepa", "Pepe", "Thomas Jefferson"] for value in myList: print(value) ``` Let's break this down a bit. Line number 1 is going to create the list and assign it to myList. Line number 2 is a **new** for loop. For loops in Python they have 2 elements. They go always for something in something(iterable). In this case we define, create a local variable with the name that we want, in this case `value`. But we can go with `x` or `number` or `fuffly` Example: ```python= myList= ["Pipo", "Pepa", "Pepe", "Thomas Jefferson"] for flufflyFlufflington in myList: print(flufflyFlufflington) ``` Now, the second part is "in something iterable". That can be a list, a calendar, a set or others, like a range (this very common). Lastly we have a colon (`:`) that is going to be very important to make it work. Line number 3 is **indented** so we have a clear vew of what is going to happen inside the loop. So if we write this ```python= myList= ["Pipo", "Pepa", "Pepe", "Thomas Jefferson"] for value in myList: print("Hi " + value) print("Bye") ``` This is going to print 4 times Hi (plus the name) and only once "Bye" ### Traversing with an enumerator Sometimes we not only need the elements but also the index of these numbers. ```python= myList= ["Pipo", "Pepa", "Pepe", "Thomas Jefferson"] for index, value in enumerate(myList): print(index, value) ``` ### Exercises of traversing These are classic algorithms that they ask in the exams as "basic that you should already know" #### Sum ```python!= myList= [5,5,17,1500,0] #first we create a count/sum variable and assign the value 0 sum = 0 for value in myList: sum = sum + value print(sum) ``` ```python!= myList= [5,5,17,1500,0] #first we create a count/sum variable and assign the value 0 sum = 0 for value in myList: sum += value print(sum) ``` #### Average First we calculate the sum, then we divide by the size of the list. An easy way to access the size is with `len()` ```python!= myList= [5,5,17,1500,0] #first we create a count/sum variable and assign the value 0 sum = 0 for value in myList: sum += value print(sum/len(myList)) ``` #### Median I know that some of you don't know what this mean yet. The idea of medians is that you get the value in the middle if the list is sorted. So for finding it out we would need to sort the array first (or even doing a copy if we want to have the original one for any reason) and access the middle value. In case the the values are even, we find the average between these 2. One simple implementation (and not complete) would be this. ```python!= myList= [5,5,17,1500,0] myList.sort() medianIndex = len(myList)//2 print(myList[medianIndex]) ``` :::info **Why using `//`?** We are using `//` instead of `/` because we want to have the integer division. If we use `/` we're going to get a float number _even if the result is a whole number_ and **indexes have to be integers**. Another solutin would be casting, writing `medianIndex = int(len(myList)/2)` to convert the result into an integer. ::: There is a more oneliner solution ```python!= myList= [5,5,17,1500,0] myList.sort() print(myList[len(myList)//2]) ``` :::info Medians are useful to spot inequalities. So if the numbers in myLists are wages, the average gives us a number, but it doesn't reflect that most of people doesn't have as much earnings as the one with 1500. So with the median we can get another different value. ::: Solution with the whole possibilities for the list to be odd or even :::spoiler ```python!= myList= [5,3,17,1500,0,4] myList.sort() print(myList) if len(myList)%2 ==1: medianIndex = len(myList)//2 print(myList[medianIndex]) else: medianIndex = len(myList)//2 other = medianIndex -1 average = (myList[medianIndex]+myList[other])/2 print(average) ``` ::: #### Minimum/maximum There are other that are the _sorting_ algorithms that we're going to dedicate a specific note on those. #### Count something that happen in an array #### Do something specific for some elements #### Parallel lists We may have more than one lists which their values in the same index refer to the same entity. When that happens we say that those lists are parallel. ```python= names = [ "Aaron", "Hamid", "Fátima"] grades = [6,5,7] ``` If we asume that Aaron has a grade 6, Hamid a 5 and Fátima a 7 (good for her) that means that both lists are parallel. In python is a bit underused this characteristic because how for loops work, but with an enumerator we can print in order all the grades and names ```python= names = [ "Aaron", "Hamid", "Fátima"] grades = [6,5,7] for index, name in enumerate(names): print(name, grades[index]) ``` ## Strings as lists ## 2 Dimensional lists in python They are like tables and they are lists of lists. Because, yeah, you can have lists inside a list. //TO-DO :::info lists in python are a bit slow in comparasion with arrays (that they have fixed size in memory). For that, however, in many cases you can use numpy, that is a library that includes a type of arrays. ![image](https://hackmd.io/_uploads/SJL8O4Z6xx.png) https://numpy.org/devdocs/user/whatisnumpy.html The idea is that behind the library there is some pre-compiled code written in c. For data science this is a basic library with pandas. But for some small programs the lists of python can work as well. ::: ### Matrixes concepts #### Diagonal (main and secondary) ### Traverse a 2D list ### Exercises #### Sum all the elements #### Average all the elements #### Minimum/maximum within all the elements #### Partial results by column or row If we have a 2dlist scores[6][5] it means that we have 6 rows and 5 columns. So the total number of elements will be 30. Usually in this cases the rows are the students and the columns the scores. So we have 6 students with 5 scores each. Output all the scores from the students. We have another array with names[6] where the name of the student is. #### Partial results by diagonals #### Partial results by another condition ## Exercises Construct a list with some specifications In a school they are going to introduce lockers that are going to have 4 different colours. The first locker (locker number 1) is going to be red, the second blue, the third green and the fourth one yellow. The fifth will be red again and so on. a. Determine the colour of the locker number 402 [1] Solution :::spoiler blue ::: b. Construct a script in python that creates a list with the 2000 lockers called `lockers`, being the first one "control" (index 0) and the rest of indexes they will correspond to each locker colour. [3] :::spoiler One option is ```python!= lockers = [] lockers.append("control") for x in range(1,2001): if x%4 == 1: lockers.append("red") if x%4 == 2: lockers.append("blue") if x%4 == 3: lockers.append("green") if x%4 == 0: lockers.append("yellow") print(lockers) print(lockers[-1]) ``` Also we can use the function lockerColour ```python!= def lockerColour(x): if x%4 == 1: return "red" if x%4 == 2: return "blue" if x%4 == 3: return "green" if x%4 == 0: return "yellow" lockers = [] lockers.append("control") for x in range(1,2001): lockers.append(lockerColour(x)) print(lockers) print(lockers[-1]) ``` ::: ## Reference https://www.w3schools.com/python/python_lists.asp https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range [Arrays in IB Pseudocode](/GOWuknHrTJSBs6NsxEeDOA) [Collections in IB Computer Science](/jJs5xsoHRjWY3n4eYzL9ZQ) DNI validator code in javascript https://gist.github.com/afgomez/5691823