Python Data Structures
Lists, Dictionaries and Tuples
Lists
• A list is an ordered sequence of information
• Uses [ ] is the notation to define an empty list
• my_list = []
• Typically list elements are homogeneous data – of all one type
• List data elements can be modified in-place.
• A data type is mutable if it can be modified after creation.
Example Lists
my_list = [] #empty list
• A list can be accessed via a specific index.
some_list = [3.141, 7, “bob”, [9,10]] • 0-indexing is a scheme whereby we start at 0 and
len(num_list) #Outputs 4. go to length – 1.
some_list[0] → 3.141 • E.g, 0, 1, 2, 3 in this case.
• We can use variables as the index value.
some_list[1] + 10 → 17
• If we go beyond the length of our list, we get an
some_list[3] → [9,10] another list error.
some_list[7] → ERROR
i = 3
some_list[i-1] → “bob” as i-1 is 2.
Nested Lists
• As Lists can contain any data object, thus we can have a list of list (or list of lists of
lists… you get the point). These are called Nested Lists
L = [ [7,8], [9,10] ]
L[0] = [7,8] → The value of L[0] is the entire list, [7,8]
L[1] = [9,10]
L[0][0] gives 7. L[0][1] gives 8. Outer, then inner.
• Avoid iterating over a list and mutating it at the same time.
• E.g. removing items whilst going through, leads to errors.
• Show example of this in action. List changes length, but python already
decided it’s going to count from 5 → 0, and suddenly the list is shorter!
List - Mutability
• Mutability allows us to modify data in-place. Why is this important?
• If we have a really large list, it means we don’t need to recreate it!
• Imagine if we had to copy 10GB List to change 1 value.
sounds = [“snap”, “crackle”, “bang”]
print(sounds[2]) # bang… doesn’t sound right
sounds[2] = “pop”
print(sounds[2]) # pop. Much better.
• Variable sounds still points to the exact same data object.
[“snap”, “crackle”, “pop”].
• It does not rebind to a new object, leaving the old in memory.
Iterating over Lists
• We can use a for loop to iterate over a list. E.g. summation
fave_n = [2, 3, 5, 7, 11]
sum = 0 sum = 0
for i in range( len(fave_n) ): for i in fave_n:
sum = sum + fave_n[i] #i-th element sum = sum + i
print(sum) print(sum)
• Remember range ‘stop’ is exclusive. 0-Indexing goes from 0 → n – 1.
• We can iterate over ‘iterable’ data objects directly.
• No need to iterate over index numbers, then index.
• Can just use the element!
Operations on Lists : append and methods
• What if we wanted to add elements, or remove them?
fave_n = [2, 3, 5, 7, 11]
fave_n[5] = “a new item” → index out of bounds!
• We can append items to the end with .append( element )
fave_n.append(97)
print(fave_n) → [2,3,5,7,11,97]
• What is .append?
• It is a method for that object.
• Using object.the_thing() is a way we can invoke that.
Operations on Lists : concatenation
• What if we have two lists of numbers
• We can concatenate two lists together.
fave_n = [2, 3, 5, 7, 11]
rob_faves = [1,6,4,3,8]
our_faves = fave_n + rob_faves
#→ [ 2, 3, 5, 7, 11, 1, 6, 4, 3, 8 ]
# fave_n and rob_faves are unchanged!
fave_n.extend(rob_faves)
# Mutates fave_n by attaching 1, 6, 4, 3, 8
Operations on Lists : del, pop & remove
• Deleting items at specific indices with del()
fave_n = [2, 3, 5, 7, 11]
del(fave_n[2]) → [2,3,7,11]
• Remove element at the end with .pop(), will return the removed element.
removed_item = fave_n.pop()
print(removed_item) → 11
• Remove a specific element itself with .remove(element)
• If not in list, gives an error.
fave_n = [2, 3, 5, 7, 11]
• If multiple, remove only first one. fave_n.remove(7)
→ [2,3, 5, 11]
Operations on Lists : Sort & Reverse
• Other operations on Lists:
• Sort the list with sorted( alist ) or alist.sort()
alist = [2, 5, 3, 11, 7]
sorted(alist) → [2,3,5,7,11] # Returns new list
alist.sort() → Mutates the original list
• Reverse a list with .reverse()
alist.reverse() → Mutates in place [11,7,5,3,2]