CODE WITH MARTIN

9. More Lists


Data Structures

There are more types of lists that each do something a little differently. There are four well known types in Python in total and these also exist in most other languages too. The first we learned was the List, the others are Tuple, Set and Dictionary.

Let's first take a look at the 'tuple' type.

Tuples

Tuples are much like lists, except intead of using square brackets to create them, we use round brackets. For example:

fruits = ("Apple", "Orange", "Banana")
print(fruits)

Just like lists, we can get the length of a tuple and access items in the tuple using square brackets, like so:

fruits = ("Apple", "Orange", "Banana")
count = len(fruits)

print(count)
print(fruits[0])

Again like lists, we can store different types in a tuple:

items = ("Apple", "Orange", "Banana", 1, 2, 3, 5.7, 10.5)
print(items)

We can create tuples from an existing list using the 'tuple' function:

fruit_list = ["Apple", "Orange", "Banana"]
fruit_tuple = tuple(fruit_list)
print(fruit_tuple)

Tuples also support the 'index' and 'count' functions that we showed in the previous lists section.

So now you're probably wondering, why on earth do I need a tuple when we have lists? What makes them different?...

Tuples are immutable (can't change) where lists are mutable (can change). With a list, you can change, insert, remove, sort and merge them with other lists. A tuple cannot do any of these things. Once a tuple is created, it is set to only allow you to read from it.

The advantage of this unchanging nature of a tuple is that they are faster than lists. Python is able to optimize how the data inside of a tuple is stored in memory compared with a list, making tuples a preferred data structure for lists of things that you won't want to change. It also protects you from making the mistake of modifying the items when you didn't really mean to, preventing software bugs.

Let's think of a few examples of lists of things that would never change and would suit being stored in a tuple rather than a list:

days = ("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")

months = (
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December")
                
seasons = ("Spring", "Summer", "Autumn", "Winter")

When you're making a list of something, always ask yourself whether you would benefit from the performance and protection of a tuple. Then all you need to remember is a tuple is made with round brackets, instead of the square brackets for a list.

Sets

Sets are another new variable type. They are very similar to both lists and tuples but with some interesting differences. The following is how we define a 'set':

fruits = {"Apple", "Orange", "Banana"}
print(fruits)

Noticed it yet? Yep, curly brackets! Lists use square brackets, tuples round and sets use curly brackets.

Sets have very interesting behaviour when we create them. Try running the following code:

fruits = {"Apple", "Apple", "Orange", "Orange"}
print(fruits)

If you look at the output in the terminal, you might notice two strange things. The first is that we added 4 strings to the set, but we only see two. This is the first interesting property of a set in that duplicate values are not allowed.

Secondly, we added "Apple" before "Orange" and yet in the output the order is reversed. Sets do not guarantee or provide any ordering of items that you add to them. This also means that sets do not support retrieving items using index numbers and square brackets like we can with tuples and lists.

Sets do allow us to add, remove, and clear them. We can also merge tuples or lists in to them. The following code shows all of these in use:

set_items = {"Red", "Blue", "Green"}
print(set_items)

set_items.remove("Blue")
print(set_items)

set_items.add("Yellow")
print(set_items)

color_list = ["Purple", "Pink"]
set_items.update(color_list)
print(set_items)

set_items.clear()
print(set_items)

You're absolutely dying to know now what sets are useful for, right? The main use of a set is for membership logic. When you need a list of things that have to be unique and you only care about checking if something exists in a list of things, this is what sets are good at.

We haven't demonstrated how to check a set to see if an item exists as this requires us to know about conditional logic. We cover this in an upcoming chapter very soon.

Dictionary

Finally, we have dictionaries. Let's consider some code showing a dictionary:

product = {
    "name": "Yankee Candle - Moonlight Cove",
    "price": 19.99,
    "weight": 1.37
}

print(product)

Dictionaries are created using curly brackets '{ }'. Each item in a dictionary has two parts. There is the key and the value. A key and value are separated by the colon character ':'. Each item (or key-value pair) in the dictionary is separated by the comma character ','. The easiest way to spot a dictionary is seeing that they use curly brackets and contain the colon character seperating two values.

In the code example above, there are 3 items in the dictionary on lines 2 to 4. There are 3 keys in this dictionary, they are named "name", "price" and "weight" and they are strings. Keys in a dictionary must be unique. Key types can vary, they don't have to all be strings like we show, you can have integers or even floats as a key.

The values associated with the keys can also be of any type. The "name" key has a value that is a string, but the "price" and the "weight" keys have values that are floats.

You can add new items to a dictionary by using the square brackets and using an index that does not exist as a key in the dictionary. Here's an example:

product = {
    "name": "Yankee Candle - Moonlight Cove",
    "price": 19.99,
    "weight": 1.37
}

product["length"] = 5

print(product)

On line 7, because "length" does not exist as a key in the dictionary variable 'product', it is added to the dictionary.

You can update the values of existing keys using the square brackets too. Example:

product = {
    "name": "Yankee Candle - Moonlight Cove",
    "price": 19.99,
    "weight": 1.37
}

print(product)

product["price"] = 25.99

print(product)

Using the square brackets without the '=', will retrieve the value for that key. Example:

product = {
    "name": "Yankee Candle - Moonlight Cove",
    "price": 19.99,
    "weight": 1.37
}

print(product["name"])

We can combine other data structures like lists and use them as values in a dictionary item. This is really helpful for describing things in a more detailed way. For example:

employee = {
    "name": "Sid",
    "title": "Software Developer",
    "languages": ["Python", "C++", "JavaScript"]
}

print(employee)

The key "languages" on line 4 has a value that is a list. Before you ask, yes, you could even use another dictionary as a value for a key if you want to get really fancy.

A dictionary is really useful when you have some data that you want to store and later retrieve using a unique ID. For example, a list of employees can be stored with a key that represents their employee ID (an integer). The employee ID is unique so works well in a dictionary.

When looking for items in a dictionary using a key, dictionaries are really fast at finding the value for you. It's much faster than trying to find data in a list. You can have thousands of items in a dictionary and finding values is just as fast as a dictionary only containing 10 items. But for lists, as you add more items to them and try to find things, they get slower. This is a dictionaries biggest advantage.

Summary

Phew, what a big topic. There are lots of details to remember around data structures which won't all sink in in one day. As we write and practice code later on, all of this will become easier to remember. Don't worry too much about remembering all the fine detail, just know that you can always come back here later on when you start needing to check up on things.

We will revisit all the data structures we've learned in the upcoming chapters. I promise they will make much more sense in their usefulness. We're just missing a little more Python knowledge to know how to really use these data structure in the real world, but eventually, you'll be using them in every single project you create.

My goal at the moment is making you aware that they exist and what the basic usage of them are so don't stress too much about them for now.

What We Learned