A list is the first type of data structure that we meet in this course. While "data structure" may sound complicated, is just a collection of data elements (e.g. numbers or strings) that is structured in some way (e.g. by numbering the elements). The list is a sequence, where each element has an index, i.e. its position in the list.
You can create a new list using the square brackets []
, or the list()
function:
list1 = ["first", "second", "third"]
list2 = list((1,2,3))
list3 = ['cake', 4, 7.9, "apple"]
Properties of lists to remember:
list3
)Just like you did this morning - accessing elements of strings - elements in a list are accessed by their index.
Remember:
[]
list1[1]
'second'
list1[0]
'first'
negative indexes go back from the end:
list1[-1]
'third'
Trying to access an element in a list that is out of range throws an IndexError
; good to know how long the list is ...
list1[4]
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-7-b02c477e8a73> in <module>() ----> 1 list1[4] IndexError: list index out of range
len(list1)
3
Remember that lists are mutable? This means that we can change, add and remove items from a list!
list2
[1, 2, 3]
list2[0] = 4
list2
[4, 2, 3]
Assigning to a position past the end of the list also throws an IndexError
list2[5] = 9
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-12-c1b1fb30f16a> in <module>() ----> 1 list2[5] = 9 IndexError: list assignment index out of range
list1.append("fourth")
list1
['first', 'second', 'third', 'fourth']
If you want to append more than one item, you can use the extend
function:
list1.extend()
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-15-4f4f0d499a0f> in <module>() ----> 1 list1.extend() TypeError: extend() takes exactly one argument (0 given)
Items at arbitrary positions can be removed using the del
statement:
list1
['first', 'second', 'third', 'fourth']
del(list1[2])
list1
['first', 'second', 'fourth']
Alternatively, you can use the pop
function:
list1.pop()
'fourth'
list1.pop(1)
'second'
insert
function: insert(index, item)
list1.insert(2, "three")
list1
['first', 'three']
note: appending items to the end of the list using append
is more efficient than inserting at the end
list4 = list1 + list2 + list3
list4
['first', 'three', 4, 2, 3, 'cake', 4, 7.9, 'apple']
Multiplying a list by a number does not multiply the elements of the list, but the whole list:
(NB: this is specific to sequences. Other data structures have element-wise multiplication as you will see later in the course)
list5 = list4 * 5
list5
['first', 'three', 4, 2, 3, 'cake', 4, 7.9, 'apple', 'first', 'three', 4, 2, 3, 'cake', 4, 7.9, 'apple', 'first', 'three', 4, 2, 3, 'cake', 4, 7.9, 'apple', 'first', 'three', 4, 2, 3, 'cake', 4, 7.9, 'apple', 'first', 'three', 4, 2, 3, 'cake', 4, 7.9, 'apple']
A copy of a sublist can be created using the slice operator list[start:end]
The element at the index start is included, the one at end is excluded (remember slicing strings with Fabian this morning?)
Both indices can be ommitted, defaulting to the start and end of the list respectively
list4[0:5]
len(list4[0:5])
list4[0:5]
['first', 'three', 4, 2, 3]
list4[4:]
[3, 'cake', 4, 7.9, 'apple']
list4[:6]
['first', 'three', 4, 2, 3, 'cake']
list4[:]
['first', 'three', 4, 2, 3, 'cake', 4, 7.9, 'apple']
to slice in bigger steps, include a stepsize:
list4[0::2]
['first', 4, 3, 4, 'apple']
NB: in Python, all variables are references
The =
operator does not copy an object, it just creates another reference (name) for the same object!
list5 = list4
list5
['first', 'three', 4, 2, 3, 'cake', 4, 7.9, 'apple']
list5.pop()
'apple'
list5 = list4
Check: they both point to the same memory address; i.e. both list1
and list5
refer to the same list.
print(id(list5))
print(id(list4))
892707494536 892707494536
-> if you want to create a new list with the same contents as another list, you need to copy it
range()
¶range([start], end)
function creates such listsmyrange = list(range(10))
myrange
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
range(3,15)
range(3, 15)
list(range(3,15))
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
For
Loops¶When programming, you often want to do the same task for each point in a data set. Some examples:
Notice how the structure of the programming command follows a natural logic: FOR each item: DO some action
tutors = ['Fabian', 'Lea', 'Dimitris', 'Joe', 'Ingolf']
for index, name in enumerate(tutors):
print (index)
print (name)
0 Fabian 1 Lea 2 Dimitris 3 Joe 4 Ingolf
for name in tutors:
print(len(name))
6 3 8 3 6
range()
¶range()
returns a list of plain integers.
Thus, one way to loop over a sequence is to use range()
on the length of a sequence -> the returned list are the indexes of the sequence. You can then access each element by index:
range(5)
range(0, 5)
for i in range(len(tutors)):
print(tutors[i])
Fabian Lea Dimitris Joe Ingolf
enumerate()
¶enumerate()
returns a tuple containing a count and the values obtained from iterating over sequence. This is handy if you need both the item a sequence and its index.
for index,name in enumerate(tutors):
print(index, name)
0 Fabian 1 Lea 2 Dimitris 3 Joe 4 Ingolf
We have seen how for
loops allow us to easily execute the same statement for each item in a list. But what if we want to apply different statements, depending on the item?
In our earlier example, say you want to print the name, but only if it contains the letter i. So now when you initialize the iterator, there are actually 2 different options and we need to check which one is the case:
if the name contains the letter i -> print the name --> whiteboard
These check-points are called conditionals; you check whether a condition is met. And the whole concept is referred to as flow control, because at these check points, you control "in which direction the programme is going to flow".
if
¶use the if
keyword to check whether a condition is met:
for number in range(8):
if number % 2 == 0:
print(number, ' is even')
0 is even 2 is even 4 is even 6 is even
use the else
keyword to specify a statement that is executed when the condition is not true:
else
¶for number in range(8):
if number % 2 == 0:
print(number, 'is even')
else:
print(number, 'is odd')
0 is even 1 is odd 2 is even 3 is odd 4 is even 5 is odd 6 is even 7 is odd
use the elif
keyword to check for several conditions:
elif
¶for number in range(8):
if number % 2 ==0:
print(number, 'is even')
elif number == 3:
print(number, 'is my favourite number!')
else:
print(number, 'is odd')
0 is even 1 is odd 2 is even 3 is my favourite number! 4 is even 5 is odd 6 is even 7 is odd
question: which expressions can you use as condition for an if statement?
True
and False
Numeric types can be compared using the comparison operators, which yield True or False The operators are:
a < b | a less than b
a > b | a greater than b
a == b | a equal to b
a <= b | a less than or equal to b
a >= b | a greater than or equal to b
The boolean values True
and False
can be combined using the boolean operators and
, or
, and not
a = True
b = False
a and b
False
a and 3 <= 4
True
here the keyword is in
mondaytutors = ["Fabian", "Lea", "Dimitris, Ingolf"]
alltutors = ["Fabian", "Joe", "Ingolf", "Lea", "Alison", "Matthias", "Michael", "Thanapong", "Peter",
"Dimitris", "Sheen", "Chris", "Auro", "Gaurav", "Ope"]
for tutor in alltutors:
if tutor in mondaytutors:
print(tutor)
Fabian Lea
for
loops on lists and list comprehensions¶You commonly want to create a new list by transforming and filtering an old list:
even_numbers = []
for x in range(10):
if x % 2 == 0:
even_numbers.append(x)
even_numbers
[0, 2, 4, 6, 8]
Because this is such a common operation Python also provides a shortcut in form of list comprehensions (they are truely great!)
even_numbers = [x for x in range(10) if x % 2 == 0]
even_numbers
[0, 2, 4, 6, 8]