3. Python Data Structures

3.1. Lists

A list is a simple container object that can hold an arbitrary number of Python objects. A list can be a list of numbers, words, or a combination. Here is an example:

alist = [1, "me", 3.456, "you", 50]
print("The list is alist = {}".format(alist))
The list is alist = [1, 'me', 3.456, 'you', 50]

Alternatively we could translate the list into a string and then print it. You can tag together strings with the plus sign. which combines a string "The list is alist = " together with another string str(alist). The Python funciton str() translates a number into a string, i.e., a word and then prints the combined “word”.

print("The list is alist = " + str(alist))
The list is alist = [1, 'me', 3.456, 'you', 50]

We can access the elements of a list bit by bit using list indexation. Note that the first element in the list is at position 0.

print(alist[0])
print(alist[1])
print(alist[2])
print(alist[3])
print(alist[4])
1
me
3.456
you
50

Or prettier

print("alist[0] = {}".format(alist[0]))
print("alist[1] = {}".format(alist[1]))
print("alist[2] = {}".format(alist[2]))
print("alist[3] = {}".format(alist[3]))
print("alist[4] = {}".format(alist[4]))
alist[0] = 1
alist[1] = me
alist[2] = 3.456
alist[3] = you
alist[4] = 50

If you want to extract more than one element of a list you can use a slice operator. This basically involves the colon symbol : at the appropriate position. If you want to extract the first three elements you can simply index the list as alist[:3]. If you want to get everything from element 2 onwards you can alist[2:]

print(alist)
print("alist[0:4] = {}".format(alist[0:4]))
print("alist[:3] = {}".format(alist[:3]))
print("alist[2:] = {}".format(alist[2:]))
[1, 'me', 3.456, 'you', 50]
alist[0:4] = [1, 'me', 3.456, 'you']
alist[:3] = [1, 'me', 3.456]
alist[2:] = [3.456, 'you', 50]

If you want to grab the last element of the list you can start indexing with negative numbers.

print(alist)
print("alist[-1] = {}".format(alist[-1]))
print("alist[-2] = {}".format(alist[-2]))
print("alist[-3] = {}".format(alist[-3]))
[1, 'me', 3.456, 'you', 50]
alist[-1] = 50
alist[-2] = you
alist[-3] = 3.456

You can change elements of a list by reassigning them using their index. So if you want to replace the third element of the list with the word “Mom” you simply assign it as

alist[2] = "Mom"
print(alist)
[1, 'me', 'Mom', 'you', 50]

What about more complicated lists, where the elements inside the list are lists themselves. In this case we are dealing with nested lists. Here is an example:

myNestedList = [['Mom', 42], ['Dad', 41], ['Kids', 10, 12]]
print(myNestedList)
[['Mom', 42], ['Dad', 41], ['Kids', 10, 12]]

Now let’s see what happens if we index this list. Try the following:

print(myNestedList[0])
print('---------------')
print(myNestedList[1])
print('---------------')
['Mom', 42]
---------------
['Dad', 41]
---------------

Then try

print(myNestedList[0][0])
print('---------------')
print(myNestedList[1][0])
print('---------------')
print(myNestedList[1][1])
print('---------------')
Mom
---------------
Dad
---------------
41
---------------

Now let’s go one step deeper into the list:

print(myNestedList[1][0][0])
print('---------------')
print(myNestedList[1][0][1])
print('---------------')
print(myNestedList[1][0][2])
print('---------------')
D
---------------
a
---------------
d
---------------

This example shows how you can extract content from a list inside of a list by simply adding brackets with indexing positions to the list name. If you go outside the range of the inside list, the interpreter will throw an error:

print(myNestedList[1][0][3])
<class 'IndexError'>
string index out of range

3.2. Tuples

Are immutable lists, that once defined, cannot be changed anymore. It is a read-only list.

a_tuple = (1, "me", 3.456, "you", 50)
print(a_tuple)
(1, 'me', 3.456, 'you', 50)

Now try to change an element of the tuple and see what happens.

a_tuple[2] = "Mom"
print(a_tuple)
<class 'TypeError'>
'tuple' object does not support item assignment

Slice operators work exactly the same way as they work on lists.

3.3. Dictionaries

Dictionaries or short “dicts” are more general mappings and word list associative arrays or so called hashes. They are basically key-value pairs where a key can be almost any Python type. So instead of indexing a list with indexes (which are numbers starting from 0, 1, etc.) the indices of a dictionary can be words or other data types.

Here is a brief example where we use names of people as keys and store various information together with those keys. We can then retrieve the information of each person with the persons name.

# Defining a dictionary as adict = {'name': income}
adict = {'James': 20000}
adict['Jim'] = 50000
adict['Tom'] = 80000

We can now retrive this info using the key.

print(adict)
print(adict['James'])
print(adict['Jim'])
print(adict['Tom'])
{'Jim': 50000, 'Tom': 80000, 'James': 20000}
20000
50000
80000

You can delete an element with

del adict['James']
print(adict)
{'Jim': 50000, 'Tom': 80000}

3.4. Pitfalls

We next give a couple examples of potential pitfalls that can cause programming mistakes.

  1. Be careful how you copy a list:

list1 = [ 1,2,3,4 ]
list2 = list1
list1.append(5)
print(list1)
print(list2)
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]

What happens here is that the list [1,2,3,4] is assigned to two separate names list1 and list2. These two names now point to the same, identical list. As soon as you change the list using list1.append(5) this change will be reflected in both names of the list. If you really just want to copy the list and give that separate copy the name list2, do the following:

from copy import deepcopy

list1 = [ 1,2,3,4 ]
list2 = deepcopy(list1)
list1.append(5)
print(list1)
print(list2)
[1, 2, 3, 4, 5]
[1, 2, 3, 4]
  1. The list methods sort() and reverse() do not return a list object

list1 = [4, 3, 2, 1]
list1.sort()
print(list1)  # You cannot do: print(list1.sort())
[1, 2, 3, 4]

But if you now try:

list2 = [-1, 0] + list1.sort()
<class 'TypeError'>
can only concatenate list (not "NoneType") to list

you get an error. So here the sort() method is not returning a list object. Since we then try to add a list [-1, 0] to something that is NOT a list, the interpreter throws an error. Here is one way to fix this, use the sorted command:

list1 = [4, 3, 2, 1]
list2 = [-1, 0] + sorted(list1)
print(list1)
print(list2)
[4, 3, 2, 1]
[-1, 0, 1, 2, 3, 4]

3.5. JSON Data Format

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write and can be used to store and communicate information to other products.

It is based on key:value pairs. Many programming languages support the JSON data format. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.

In brief, JSON is a way by which we store and exchange data, which is accomplished through its syntax, and is used in many web applications. The nice thing about JSON is that it has a human readable format, and this may be one of the reasons for using it in data transmission, in addition to its effectiveness when working with APIs (Application Programming Interface).

An example of JSON-formatted data is as follows:

{"name": "Frank", "age": 39, "isEmployed": true}

Python has a built in JSON library called json that needs to be imported if you want to convert a JSON string into a Python value object like a dictionary or a list.

import json

jsonData = '{"name": "Frank", "age": 39}'
jsonToPython = json.loads(jsonData)
print(jsonToPython)
{'name': 'Frank', 'age': 39}

The JSON string has been converted to a dictionary. You can now use it as such.

print(jsonToPython['name'])
Frank

If you want to convert a Python dictionary into a JSON string that can then be written to a file and read by other programs you can use the json.dumps() function.

import json

pythonDictionary = {'name':'Bob', 'age':44, 'isEmployed':True}
dictionaryToJson = json.dumps(pythonDictionary)

print(dictionaryToJson)
{"isEmployed": true, "name": "Bob", "age": 44}

3.6. In Class Exercises

  1. Generate a list with numbers from 1 to 10

  2. Print the first 5 elements of this list

  3. Replace the last entry of the list with 100 and print the list again

  4. Sort the list from largest to smallest element