"* sorting a list: ```l.sort()```. We can add the argument ```reverse=True``` if we want the list to be sorted in reverse.\n",
"* count the number of times an element appears in the list: ```l.count(element)```\n",
"* reverse the order of elements in the list ```l.reverse()```\n",
"* find the position (index) of the first occurence of an element with value ```value```: ```l.index(value, pos)```. The second argument ```pos``` is optional, if we specify ```pos>0```, the search starts from this position (index) instead of the beginning.\n",
"\n",
"**Exercise:** \n",
"\n",
"Take the list defined below, sort it in ascending order and count how often the number 2 appears."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "yzJ9yfQfIXda"
},
"outputs": [],
"source": [
"my_list = [0,3,2,6,3,2,1,7,8,7]\n",
"\n",
"# ... your code here ...."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Removing elements from lists\n",
"\n",
"* remove all items from a list: ```l.clear()```\n",
"* remove an item at a specific index and return it: ```element = l.pop(index)```. The argument ```index``` is optional, if you do not specifiy it, it will remove and return the last element in the list.\n",
"* remove the first item with value ```value``` from the list: ```l.remove(value)```. If the ```value``` does not exist, we get an error (```ValueError```)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0, 2, 6, 3, 2, 1, 7, 8, 7]\n"
]
}
],
"source": [
"my_list = [0,3,2,6,3,2,1,7,8,7]\n",
"\n",
"# remove the first 3\n",
"my_list.remove(3)\n",
"print(my_list)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Accessing list elements and slicing\n",
"\n",
"In order to work with lists, we also need to access the elements. We can do this by using their index in the following way: ```l[index]```\n",
"Indices are counted forwards (starting from 0), i.e. the first element has ```index = 0```, the second element ```index = 1```, and so on.\n",
"However, we can also count backwards. Then, the last element has ```index = -1 ```, the second last has ```index = -2```, and so on.\n",
"\n",
""
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3, 4, 5]\n",
"-----------\n",
"3\n",
"-----------\n",
"5\n",
"5\n",
"5\n"
]
}
],
"source": [
"my_list = [1, 2, 3, 4, 5]\n",
"\n",
"# print the full list\n",
"print(my_list)\n",
"print('-----------')\n",
"\n",
"# print the second element\n",
"print(my_list[2])\n",
"print('-----------')\n",
"\n",
"# print the last element\n",
"print(my_list[4])\n",
"print(my_list[len(my_list)-1])\n",
"print(my_list[-1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There we see three ways of accessing the last element of the list\n",
"\n",
"* we happen to know that the list contains five elements, hence, the last one is at ```index = 4``` (because we start counting from zero)\n",
"* the function ```len( list )``` gives us the length of the list. We subtract one (as we start counting from zero), to get the index of the last element.\n",
"* we use the backward index and use ```index = -1``` to refer to the last element.\n",
"\n",
"> **Note:**\n",
">\n",
"> Think about which method you would use and why.\n",
"\n",
"Lists are ***mutable***, i.e. we can change the elements, e.g."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3, 4, 5]\n",
"[1, 2, 10, 4, 5]\n"
]
}
],
"source": [
"print(my_list)\n",
"\n",
"my_list[2] = 10\n",
"\n",
"print(my_list)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can access ranges of lists via the index. The general syntax is ```list [ start_index : stop_index : step_size ]```.\n",
"\n",
"\n",
"This means: \n",
"* we start our slice at ```start_index```, \n",
"* end at the ```stop_index```, and \n",
"* go ```step_size``` steps at a time. Positive step sizes mean we go forward, negative we go backward.\n",
"\n",
"All three arguments ```start_index```, ```stop_index```, and ```step_size``` are optional. If we do not specify them, this means *the rest of the list*.\n",
"\n",
"Hence ```my_list``` and ```my_list[:]``` refer to the whole list."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3, 4, 5]\n",
"[1, 2, 3, 4, 5]\n",
"-----------\n",
"[2, 3, 4, 5]\n",
"-----------\n",
"-----------\n",
"-----------\n",
"[1, 3, 5]\n"
]
}
],
"source": [
"my_list = [1, 2, 3, 4, 5]\n",
"print(my_list)\n",
"print(my_list[:])\n",
"print('-----------')\n",
"\n",
"# print the list from the second element onwards\n",
"print(my_list[1:])\n",
"print('-----------')\n",
"\n",
"# print the list up to the second last element\n",
"# should give: [1, 2, 3]\n",
"# ... your code here ....\n",
"\n",
"print('-----------')\n",
"\n",
"# print the list between the second and the second last element\n",
"# should give [2, 3]\n",
"# ... your code here ....\n",
"\n",
"print('-----------')\n",
"\n",
"# print every other element of the list\n",
"# this should give [1, 3, 5]\n",
"# ... your code here ....\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Lists and strings\n",
"\n",
"\n",
"In a way, list and strings share some similar behaviour. We can (almost) interpret a string as a list of letters. In this sense, we can also access the elemets of the string with indices as we did with lists, work with ranges, etc.\n",
"\n",
"However, crucially, strings are ***immutable***, i.e. once created we cannot change the letters at the indices."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"python\n"
]
}
],
"source": [
"my_string = 'I love python'\n",
"\n",
"index_p = my_string.index('p')\n",
"\n",
"print(my_string[index_p:])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Exercise:\n",
"\n",
"Use indices and slicing methods to print the word \"run\" from the word \"nurse\" below."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"RUN\n"
]
}
],
"source": [
"my_word = 'nurse'\n",
"\n",
"# ... your code here ..."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Tuples\n",
"\n",
"Tuples are quite similar to lists and we can also access them via their indices.\n",
"However, unlike lists, tuples are ***immutable***, i.e. once created, we cannot change the values.\n",
"\n",
"Tuples are (technically) defined by the presence of the comma, however, we typically use round brackets to make it look neater and more easily recogniseable."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(1, 2, 3, 4, 5)\n",
"-----------\n",
"(3, 4, 5)\n",
"-----------\n"
]
},
{
"ename": "TypeError",
"evalue": "'tuple' object does not support item assignment",
"Cell \u001b[0;32mIn [18], line 10\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39m-----------\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[1;32m 9\u001b[0m \u001b[39m#this will fail.\u001b[39;00m\n\u001b[0;32m---> 10\u001b[0m my_tuple[\u001b[39m1\u001b[39;49m] \u001b[39m=\u001b[39m \u001b[39m10\u001b[39m\n",
"\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment"
]
}
],
"source": [
"my_tuple = (1, 2, 3, 4, 5)\n",
"\n",
"print(my_tuple)\n",
"print('-----------')\n",
"\n",
"print(my_tuple[2:])\n",
"print('-----------')\n",
"\n",
"#this will fail.\n",
"my_tuple[1] = 10"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Set\n",
"\n",
"A set is also similar to a list - but here each element can only occur once and the order of the set is not fixed, i.e. it is an unorderd collection of distinct objects.\n",
Previously, we have seen the basic datatypes such as:
* int
* float
* string
* boolean
These are suitable to hold single values - but often, we want to create more complex datatypes that can hold more than one value.
## Lists
List are "containers" that store a sequence of elements.
We can initialise a list with a sequence of elements or start with an empty list.
We can get the length of the list by using the function ```len()```
%% Cell type:code id: tags:
``` python
my_empty_list=[]
my_list=[1,2,3,4]
# print the content of the list
print(my_list)
# print the length of the list - remember the way to format the printed statements
print('The list has {} elements'.format(len(my_list)))
```
%% Output
[1, 2, 3, 4]
The list has 4 elements
%% Cell type:markdown id: tags:
### Extending lists
There are multiple ways to add new elements to a list ```l````
(note that normally we would use more descriptive variable names instead of just "l"!)
* add a new element at the end of the list: ```l.append(element)```
* insert an element at a specific position: ```l.insert(index, element)```
* concatenating lists: ```list_1 + list_2```
%% Cell type:code id: tags:
``` python
# add a new element at the end
my_list.append(5)
print(my_list)
print('-------------')
# add a new element in the middle at index 2
my_list.insert(2,3)
print(my_list)
print('-------------')
# concatenating lists
list_1 = [1,2,3]
list_2 = [2,3,4]
my_list = list_1 + list_2
print(my_list)
print('-------------')
```
%% Output
[1, 2, 3, 3, 4, 5, 5]
-------------
[1, 2, 3, 3, 3, 4, 5, 5]
-------------
[1, 2, 3, 2, 3, 4]
-------------
%% Cell type:markdown id: tags:
### Common list operations
* sorting a list: ```l.sort()```. We can add the argument ```reverse=True``` if we want the list to be sorted in reverse.
* count the number of times an element appears in the list: ```l.count(element)```
* reverse the order of elements in the list ```l.reverse()```
* find the position (index) of the first occurence of an element with value ```value```: ```l.index(value, pos)```. The second argument ```pos``` is optional, if we specify ```pos>0```, the search starts from this position (index) instead of the beginning.
**Exercise:**
Take the list defined below, sort it in ascending order and count how often the number 2 appears.
%% Cell type:code id: tags:
``` python
my_list = [0,3,2,6,3,2,1,7,8,7]
# ... your code here ....
```
%% Cell type:markdown id: tags:
### Removing elements from lists
* remove all items from a list: ```l.clear()```
* remove an item at a specific index and return it: ```element = l.pop(index)```. The argument ```index``` is optional, if you do not specifiy it, it will remove and return the last element in the list.
* remove the first item with value ```value``` from the list: ```l.remove(value)```. If the ```value``` does not exist, we get an error (```ValueError```)
%% Cell type:code id: tags:
``` python
my_list = [0,3,2,6,3,2,1,7,8,7]
# remove the first 3
my_list.remove(3)
print(my_list)
```
%% Output
[0, 2, 6, 3, 2, 1, 7, 8, 7]
%% Cell type:markdown id: tags:
### Accessing list elements and slicing
In order to work with lists, we also need to access the elements. We can do this by using their index in the following way: ```l[index]```
Indices are counted forwards (starting from 0), i.e. the first element has ```index = 0```, the second element ```index = 1```, and so on.
However, we can also count backwards. Then, the last element has ```index = -1 ```, the second last has ```index = -2```, and so on.

%% Cell type:code id: tags:
``` python
my_list = [1, 2, 3, 4, 5]
# print the full list
print(my_list)
print('-----------')
# print the second element
print(my_list[2])
print('-----------')
# print the last element
print(my_list[4])
print(my_list[len(my_list)-1])
print(my_list[-1])
```
%% Output
[1, 2, 3, 4, 5]
-----------
3
-----------
5
5
5
%% Cell type:markdown id: tags:
There we see three ways of accessing the last element of the list
* we happen to know that the list contains five elements, hence, the last one is at ```index = 4``` (because we start counting from zero)
* the function ```len( list )``` gives us the length of the list. We subtract one (as we start counting from zero), to get the index of the last element.
* we use the backward index and use ```index = -1``` to refer to the last element.
> **Note:**
>
> Think about which method you would use and why.
Lists are ***mutable***, i.e. we can change the elements, e.g.
%% Cell type:code id: tags:
``` python
print(my_list)
my_list[2] = 10
print(my_list)
```
%% Output
[1, 2, 3, 4, 5]
[1, 2, 10, 4, 5]
%% Cell type:markdown id: tags:
We can access ranges of lists via the index. The general syntax is ```list [ start_index : stop_index : step_size ]```.
This means:
* we start our slice at ```start_index```,
* end at the ```stop_index```, and
* go ```step_size``` steps at a time. Positive step sizes mean we go forward, negative we go backward.
All three arguments ```start_index```, ```stop_index```, and ```step_size``` are optional. If we do not specify them, this means *the rest of the list*.
Hence ```my_list``` and ```my_list[:]``` refer to the whole list.
%% Cell type:code id: tags:
``` python
my_list = [1, 2, 3, 4, 5]
print(my_list)
print(my_list[:])
print('-----------')
# print the list from the second element onwards
print(my_list[1:])
print('-----------')
# print the list up to the second last element
# should give: [1, 2, 3]
# ... your code here ....
print('-----------')
# print the list between the second and the second last element
# should give [2, 3]
# ... your code here ....
print('-----------')
# print every other element of the list
# this should give [1, 3, 5]
# ... your code here ....
```
%% Output
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
-----------
[2, 3, 4, 5]
-----------
-----------
-----------
[1, 3, 5]
%% Cell type:markdown id: tags:
### Lists and strings
In a way, list and strings share some similar behaviour. We can (almost) interpret a string as a list of letters. In this sense, we can also access the elemets of the string with indices as we did with lists, work with ranges, etc.
However, crucially, strings are ***immutable***, i.e. once created we cannot change the letters at the indices.
%% Cell type:code id: tags:
``` python
my_string = 'I love python'
index_p = my_string.index('p')
print(my_string[index_p:])
```
%% Output
python
%% Cell type:markdown id: tags:
Exercise:
Use indices and slicing methods to print the word "run" from the word "nurse" below.
%% Cell type:code id: tags:
``` python
my_word = 'nurse'
# ... your code here ...
```
%% Output
RUN
%% Cell type:markdown id: tags:
## Tuples
Tuples are quite similar to lists and we can also access them via their indices.
However, unlike lists, tuples are ***immutable***, i.e. once created, we cannot change the values.
Tuples are (technically) defined by the presence of the comma, however, we typically use round brackets to make it look neater and more easily recogniseable.
TypeError: 'tuple' object does not support item assignment
%% Cell type:markdown id: tags:
## Set
A set is also similar to a list - but here each element can only occur once and the order of the set is not fixed, i.e. it is an unorderd collection of distinct objects.