Exploring Python data structures
In this section, we will review different types of data structures, including lists, tuples, and dictionaries. We will see methods and operations for managing these data structures and practical examples where we review the main use cases.
Lists
Lists in Python are equivalent to structures as dynamic vectors in programming languages such as C. We can express literals by enclosing their elements between a pair of brackets and separating them with commas. The first element of a list has index 0
.
Consider the following example: a programmer can create a list using the append()
method by adding objects, printing the objects, and then sorting them before printing again. We describe a list of protocols in the following example, and use the key methods of a Python list as add
, index
, and remove
:
>>> protocolList = [] >>> protocolList.append(“ftp”) >>> protocolList.append(“ssh”) >>> protocolList.append(“smtp”) >>> protocolList.append(“http”) >>> print(protocolList) [‘ftp’,’ssh’,’smtp’,’http’] >>> protocolList.sort() >>> print(protocolList) [‘ftp’,’http’,’smtp’,’ssh’] >>> type(protocolList) <type ‘list’> >>> len(protocolList) 4
To access specific positions, we can use the index()
method, and to delete an element, we can use the remove()
method:
>>> position = protocolList.index(“ssh”) >>> print(“ssh position”+str(position)) ssh position 3 >>> protocolList.remove(“ssh”) >>> print(protocolList) [‘ftp’,’http’,’smtp’] >>> count = len(protocolList) >>> print(“Protocol elements “+str(count)) Protocol elements 3
To print out the whole protocol list, use the following instructions. This will loop through all the elements and print them:
>>> for protocol in protocolList: >>> print (protocol) ftp http smtp
Lists also have methods that help manipulate the values within them and allow us to store more than one variable within them and provide a better way to sort object arrays in Python. These are the techniques commonly used to control lists:
.append(value)
: Appends an element at the end of the list.count(‘x’)
: Gets the number of ‘x’ in the list.index(‘x’)
: Returns the index of ‘x’ in the list.insert(‘y’,’x’)
: Inserts ‘x’ at location ‘y’.pop()
: Returns the last element and also removes it from the list.remove(‘x’)
: Removes the first ‘x’ from the list.reverse()
: Reverses the elements in the list.sort()
: Sorts the list in ascending order
The indexing operator allows access to an element and is expressed syntactically by adding its index in brackets to the list, list [index]
. You can change the value of a chosen element in the list using the index between brackets:
protocols[4] = ‘ssh’ print(“New list content: “, protocols)
Also, you can copy the value of a specific position to another position in the list:
protocols[1] = protocols[4] print(“New list content:”, protocols)
The value inside the brackets that selects one element of the list is called an index, while the operation of selecting an element from the list is known as indexing.
Adding elements to a list
We can add elements to a list by means of the following methods:
list.append(value)
: This method allows an element to be inserted at the end of the list. It takes its argument’s value and puts it at the end of the list that owns the method. The list’s length then increases by one.list.insert(location, value)
: Theinsert()
method is a bit smarter since it can add a new element at any place in the list, and not just at the end. It takes as arguments first the required location of the element to be inserted and then the element to be inserted.
Reversing a list
Another interesting operation that we perform in lists is the one that offers the possibility of getting elements in a reverse way in the list through the reverse()
method:
>>> protocolList.reverse() >>> print(protocolList) [‘smtp’,’http’,’ftp’]
Another way to do the same operation is to use the -1 index. This quick and easy technique shows how you can access all the elements of a list in reverse order:
>>> protocolList[::-1] >>> print(protocolList) [‘smtp’,’http’,’ftp’]
Searching elements in a list
In this example, we can see the code for finding the location of a given element inside a list. We use the range
function to get elements inside protocolList
and we compare each element with the element to find. When both elements are equal, we break the loop and return the element.
You can find the following code in the search_element_list.py
file:
protocolList = [“FTP”, “HTTP”, “SNMP”, “SSH”] toFind = “SSH” found = False for i in range(len(protocolList)): found = protocolList[i] == toFind if found: break if found: print(“Element found at index”, i) else: print(“Element not found”)
Now that you know how to add, reverse, and search for elements in a list, let’s move on to learning about tuples in Python.
Tuples
A tuple is like a list, except its size cannot change and cannot add more elements than originally specified. The parentheses delimit a tuple. If we try to modify a tuple element, we get an error that indicates that the tuple object does not support element assignment:
>>>tuple=(“ftp”,”ssh”,”http”,”snmp”) >>>tuple[0] ‘ftp’ >>>tuple[0]=”FTP” Traceback (most recent call last): File “<stdin>”, line 1, in <module> TypeError: ‘tuple’ object does not support item assignment
Now that you know the basic data structures for working with Python, let’s move on to learning about Python dictionaries in order to organize information in the key-value format.
Python dictionaries
The Python dictionary data structure is probably the most important in the entire language and allows us to associate values with keys. A key is any immutable object. The value associated with a key can be accessed with the indexing operator. In Python, dictionaries are implemented using hash tables.
A Python dictionary is a way of storing information in the format of key: value
pairs. Python dictionaries have curly brackets, {}
. Let’s look at a protocols dictionary, with names and numbers, for example:
>>> services = {“ftp”:21, “ssh”:22, “smtp”:25, “http”:80}
The limitation with dictionaries is that we cannot use the same key to create multiple values. This will overwrite the duplicate key preceding value.
Using the update
method, we can combine two distinct dictionaries into one. In addition, the update
method will merge existing elements if they conflict:
>>> services = {“ftp”:21, “ssh”:22, “smtp”:25, “http”:80} >>> services2 = {“ftp”:21, “ssh”:22, “snmp”:161, “ldap”:389} >>> services.update(services2) >>> print(services) {“ftp”:21, “ssh”:22, “smtp”:25, “http”:80,”snmp”:161, “ldap”:389}
The first value is the key, and the second the key value. We can use any unchangeable value as a key. We can use numbers, sequences, Booleans, or tuples, but not lists or dictionaries, since they are mutable.
The main difference between dictionaries and lists or tuples is that values contained in a dictionary are accessed by their name and not by their index. You may also use this operator to reassign values, as in the lists and tuples:
>>> services[“http”]= 8080
This means that a dictionary is a set of key-value pairs with the following conditions:
- Each key must be unique: That means it is not possible to have more than one key of the same value.
- A key may be data of any type: It may be a number or a string.
- A dictionary is not a list: A list contains a set of numbered values, while a dictionary holds pairs of values.
- The len() function: This works for dictionaries and returns the number of key-value elements in the dictionary.
Important note
In Python 3.7, dictionaries have become ordered collections by default.
When building a dictionary, each key is separated from its value by a colon, and we separate items by commas. The .keys()
method will return a list of all keys of a dictionary and the .items()
method will return a complete list of elements in the dictionary. The following are examples involving these methods:
services.keys()
is a method that will return all the keys in the dictionary.services.items()
is a method that will return the entire list of items in a dictionary:
>>> keys = services.keys() >>> print(keys) [‘ftp’, ‘smtp’, ‘ssh’, ‘http’, ‘snmp’]
Another way is based on using a dictionary’s method called items()
. The method returns a list of tuples (this is the first example where tuples are something more than just an example of themselves) where each tuple is a key-value pair:
- Enter the following command:
>>> items = services.items() >>> print(items) [(‘ftp’, 21), (‘smtp’,25), (‘ssh’, 22), (‘http’, 80), (‘snmp’, 161)]
From the performance point of view, when it is stored, the key inside a dictionary is converted to a hash value to save space and boost efficiency when searching or indexing the dictionary. The dictionary may also be printed, and the keys browsed in a particular order.
- The following code sorts the dictionary elements in ascending order by key using the
sort()
method:>>> items.sort() >>> print(items) [(‘ftp’, 21), (‘http’, 80), (‘smtp’, 25), (‘snmp’, 161), (‘ssh’, 22)]
- Finally, you might want to iterate over a dictionary and extract and display all the key-value pairs with a classical
for
loop:>>> for key,value in services.items(): >>> print(key,value) ftp 21 smtp 25 ssh 22 http 80 snmp 16
Assigning a new value to an existing key is simple due to dictionaries being fully mutable. There are no obstacles to modify them:
- In this example, we’re going to replace the value of the
http
key:>>> services[‘http’] = 8080 >>> print(services) {“ftp”:21, “ssh”:22, “smtp”:25, “http”:8080,”snmp”:161}
- Adding a new key-value pair to a dictionary is as easy as modifying a value. Only a new, previously non-existent key needs to be assigned to one:
>>> services[‘ldap’] = 389 >>> print(services) {“ftp”:21, “ssh”:22, “smtp”:25, “http”:8080,”snmp”:161, “ldap”:389}
Note that this is very different behavior compared to lists, which don’t allow you to assign values to non-existing indices.
Now that you know the main data structures for working with Python, let’s move on to learning how to structure our Python code with functions and classes.