Containers¶
You were previously introduced to the following basic data types in Python: Boolean
, int
, float
and str
. There are more fundamental data structures in Python which you will learn about in this notebook.
These collections of data types are like containers that can contain several items. In particular, this notebook covers:
list
set
tuple
dictionary
Lists part 1¶
A list is a container of ordered elements that can be accessed by their index.
- To create an empty list use square brackets
[]
- The elements in a list are separated by commas.
#declare an empty list
empty_list = []
print(empty_list)
#declare a list with soem items
tasks = ["Install Python", "Learn Python", "Take a break"]
print(tasks)
- To find out how many elements there are in a list, you can use the built-in function
len
.
len(tasks)
Accessing values in a list
¶
The elements in a list are ordered and can thus be accessed by their index. Lists start counting at 0
, i.e. the first element in your list lives at the index position 0
.
Accessing single elements¶
friends = ["Rachel", "Monica", "Phoebe"]
friends[0]
print(friends[2])
print(friends[3]) # IndexError
To access values from the end, you can use a negative number to index backwards:
print(friends[-1])
print(friends[-3])
print(friends[-4]) # IndexError
Setting elements
You can set, i.e. re-define elements in an existing list with the assignment operator
print(friends)
print(friends[1])
friends[1] = 'Chandler'
print(friends)
To check if a value is in a list, you can use the in
operator:
print("Rachel" in friends)
print("Jason" in friends)
print("rachel" in friends)
Accessing multiple elements: slicing¶
To access several elements at once, you can use a technique called slicing:
some_list[start:end:step]
Slicing returns a sublist of the original list (up to the entire original list).
The special thing about slicing is that none of the parameters are required. By selectively including thme we can do certain things, see below.
friends = ["Rachel", "Monica", "Phoebe", 'Joey', 'Chandler', 'Ross']
If you don't specify the end
parameter the slice will extend all the way to the end of the list:
#only using the start parameter
# slice from index 1 (this is the second element in the list) and all the way to the end
print(friends[1:])
# slice from index 2
print(friends[2:])
We can also negate the parameter to count from the back, like we did when accessing single values.
# slice starting from the third element from the back and going forwards
print(friends[-3:])
We can include the end
parameter to extract a slice from element 2 to 4.
Be mindful that the end
itself is not included! Also, remember that the first element is at index 0, not index 1. It takes some practise to get exactly the part you want.
# slice from index 2 to 4
print(friends[2:5])
# slice starting from index 2 up to (but excluding) index 4
print(friends[2:4])
When we do not specify the start
it will automatically be the beginning of the list (index 0). Notice that we have to put a colon :
in front of the end
parameter so python knows it's the end
, not the start
.
# slice up to (but excluding) index 4
print(friends[:4])
The end
parameter can be negative, just like the the start
. In that case we count from the end of the list.
# slice up to the (but excluding) the last element
# = the first element from the end
print(friends[:-1])
The step
parameter indicated that step size. If you leave it out, the step size is 1. This was done in all the examples so far.
By modifying the step size we can do things like accessing only every nth element:
# access entire list from start to end, but only count every other element
print(friends[::2])
When the step size is negative we move in the opposite direction, i.e. from the end towards the front of the list.
print(friends[::-1])
Exercise 1¶
~ 20 minutes
a. Defining a list¶
Let's start with defining a list called random_things
that is at least 4 elements long. The data is completely up to you, but it must contain at least 1 str
and 1 float
.
Use the len
function to check if your list is indeed at least 4 elements long.
# your code goes here
b. Slicing¶
Next, we should practice accessing elements in a list.
sund_centers = ['BRIC', 'CPR', 'CBMR', 'reNEW', 'CTN', 'HeaDS', 'Globe', 'Vet', 'Pharma']
###
# your code goes below
###
# display the first element in sund_centers
# display the last element in sund_centers
# display all but the last element in sund_centers
# display the last 3 elements
# display every second element
# display ever second element starting from 'CPR'
Quiz
Given a list numbers = ['one','two','three','four']
- what do the following slices return and why?
slice 1
numbers[::-1]
:(a)
['one','two','three','four']
(b)['one','four']
(c)['four','three','two','one']
(d)['four']
slice 2:
numbers[1:3]
:(a)
['one','two','three']
(b)['two','three']
(c)['two','three','four']
(d)['one','two']
(e)['three']
slice 3:
numbers[-2]
:(a)
['three']
(b)'three'
(c)['one','two','three']
(d)['two']
(e)'two
# if you are unsure, just try it out here
c. Setting values¶
Here you have a list of names, but it contains a few spelling errors. Correct the entries in the list by accessing an element by its index and assigning a new string.
- Change "Petre" to "Peter"
- Change "Monika" to "Monica"
- Change "george" to "George" (capitalize it)
people = ["Petre","Joanna","Louis","Angie","Monika","george"]
# your code goes here
Lists part 2¶
Nested Lists¶
Lists can contain any kind of element, even other lists!
nested_list = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
print(nested_list)
You access the individual sublists in the same way as we accessed simple elements before:
# returns the first sublist
nested_list[0]
To access an element inside a sublist of a list, you first need to access the sublist by its index and then the element in the sublist by its index in the sublist:
# This will return 2, the 1st element in the 0th sublist.
nested_list[0][1]
Did you know that strings behave a lot like lists, too? They are what we call subscriptable
. A string is not a simple element like an integer. It consists of a sequence of characters, which you can access just like list elements.
my_string = "Programming is fun!"
print(my_string[:11])
print(my_string[-4:])
print(my_string[::-1])
List Methods¶
Working with lists is very common - here are a few things we can do!
Adding elements to a list:
append
: add an item to the end of the list.extend
: add to the end of a list all values passed to extend.insert
: insert an item at a given position.
Note on append/extend: append is for adding single elements, extend for appending multiple elements from another iterable
# append
first_list = ['one', 'two', 'three', 'four']
first_list.append('five')
print(first_list)
# but careful with this one!
first_list = ['one', 'two', 'three', 'four']
first_list.append(['five','six'])
print(first_list)
# extend
correct_list = ['one', 'two', 'three', 'four']
correct_list.extend(['five','six', 'seven', 'eight'])
print(correct_list)
# insert
first_list = ['one', 'two', 'three', 'four']
first_list.insert(2, 'Hi!')
print(first_list)
Removing elements from a list:
clear
: remove all items from a list.pop
- Remove the item at the given position in the list, and return it.
- If no index is specified, removes & returns last item in the list.
del
: deletes a value from a list.
# clear
first_list = ['one', 'two', 'three', 'four']
first_list.clear()
print(first_list)
# pop
first_list = ['one', 'two', 'three', 'four']
last_item = first_list.pop()
print(last_item)
second_item = first_list.pop(1)
print(second_item)
# the elements are then not in the list anymore
print(first_list)
# del
first_list = ['one', 'two', 'three', 'four']
del first_list[3]
print(first_list)
del first_list[1]
print(first_list)
Other useful list methods:
count
: return the number of times x appears in the list.sort
: sort the items of the list (in-place).copy
: take a list and assign a copy to a new variable.
# count
numbers = [1, 2, 3, 4, 3, 2, 1, 4, 10, 2]
# count how often 2 appears in the list
print(numbers.count(2))
# count how often 21 appears in the list
print(numbers.count(21))
# sort
another_list = [6, 4, 1, 2, 5]
another_list.sort()
print(another_list)
# copy
unsorted_list = [6, 4, 1, 2, 5]
# just assigning a list to a new variable name does not copy it
# you now simply have to variable names pointing to the same list
sorted_list = unsorted_list
sorted_list.sort()
print(sorted_list)
print(unsorted_list)
# this is the way to copy a list
import copy
unsorted_list = [6, 4, 1, 2, 5]
sorted_list = copy.deepcopy(unsorted_list)
sorted_list.sort()
print(sorted_list)
print(unsorted_list)
Exercise 2¶
~15 minutes
Find the instructions as comments.
shopping_list = [['apples','bananas','oranges'],
['milk', 'eggs', 'cheese'],
['soap', 'toothbrush', 'tissues']]
# your code goes here
# add one item to every sublist in shopping_list
# remove the last sublist from shopping_list
# make a copy of the shopping list called new_list
# make new_list a 'flat' list (non-nested) without changing the original shopping_list
# Tip: take the first sublist and extend it with the second
Sets¶
A set is a collection of unqiue, unordered, (unchangeable,) and unindexed elements.
- To create an empty set:
- use curly brackets
{}
.
- use curly brackets
- Unique elements: Each element in a set can only appear once.
- Unordered and unindexed elements: In a set, you cannot know in which order the elements might appear. Since the elements can appear in any order, they do not have an index and you therefore cannot access the elements of a set by an index.
- "Unchangeable" elements: You cannot change or update the elements of a set, but you can remove or add new items.
# create a set
number_set = {1,2,3}
Why is this useful?
I personally like it to get all unique values in a list.
my_list = [1,4,7,1,2,3,3,7,2,7,7,1]
set(my_list)
Having set objects allows you to perform set operations such as:
- union
- intersection
- set difference
fav_foods = {'pizza', 'pasta', 'sushi','ice cream'}
deserts = {'cake', 'pancake', 'ice cream'}
carbs = {'pizza', 'pasta', 'potatoes'}
asian_foods = {'pho', 'stir fry', 'sushi'}
# Which of my favorite foods are also carbs?
fav_foods.intersection(carbs)
# Its diet week and we're not having desert. Which foods are left from the favorite set?
# Notice that difference is directional! What do you get if you swap the sets below?
fav_foods - deserts
# Lets say a restaurant wants to do everything from the deserts and carbs sets, whats their entire menu?
menu = deserts.union(carbs)
menu
Dictionaries¶
A dictionary stores (key, value) pairs.
- Dictionaries are created with curly brackets
{key: value}
- Dictionaries are ordered by insertion order since
Python 3.5
. - Dictionary values are accessed by keys.
- Each key in the dictionary is unique and duplicates are not allowed.
# define dictionary
city_population = {
'Tokyo': 13350000, # a key-value pair
'Los Angeles': 18550000,
'New York City': 8400000,
'San Francisco': 1837442,
}
# display dictionary
city_population
# access the value for the key 'New York City'
print(city_population['New York City'])
Change values by specifying the key and using the =
operator:
city_population['New York City'] = 73847834
city_population
To add a new (key, value) pair, you can choose between different ways:
# using the = operator
city_population['Copenhagen'] = 1000000
# using the update method
city_population.update({'Barcelona': 5000000})
city_population
A dictionary can hold complex data types as values:
food = {"fruits": ["apple", "orange"], "vegetables": ["carrot", "eggplant"]}
# access the value of the key "fruits"
print(food["fruits"])
# access element at index 0 in the list
print(food["fruits"][0])
To remove a (key, value) pair from the dictionary:
food
del food['vegetables']
food
Tuples¶
A tuple is an (immutable) ordered container of values.
- To create a tuple, use round brackets
()
. - "Immutable" means that the elements of a tuple can only be accessed, but not changed.
- Tuples can be used as keys in dictionaries and as elements of sets whereas lists cannot!
# create a tuple
t = (5, 6)
# equal formulation
#t = 5, 6
t
# a tuple can have an arbitrary amount of elements:
t2 = (1,2,5,3,8,11)
t2
Exercise 3¶
~ 15 minutes
- Create a dictionary with 4 elements.
- Create a dictionary called countries where the key is the country and the value is a (non-exhaustive) list of cities in the country.
- Access one of the keys.
- Access one of the values, i.e. cities belonging to that key.
- Add another country and its list of cities.
- Remove one of the countries and its elements.