Re-introduction to Python - part 2. Applying logic to collections of data.
In Part 1 we learned about data types and variables. We saw how basic data types like numbers, strings, dates, etc., can be combined into composite data types like lists of items. Lists are very widely used in Python programmes, because they give us a simple way of keeping a collection of items (possibly of different data types) and manipulating that collection as a whole.
As the point of programming is to automate tasks, we often want to be able to apply some operations to every element of a list - regardless of how many items there are in the list or what their specific values are. Remember how I said good programmers can be a bit lazy? Well this is where the transfer of labour happens, from human to machine. Yes, it takes the computer a longer time to process a list of 30 million items than to process a single item. But that's what computers are for, right? They get faster and faster each year, so they can do things like that. In contrast, it takes us only a one-time effort to define the operation we want to be applied to each item.
So I strongly advise you to get well familiar with Python lists and the various operations that can be performed on them. It's important to remember a list is an ordered collection of items. In the computer memory, the items are stored in the order you define (or add) them. So the list [1,2,3]
is different from the list [1, 3, 2]
. Lists can also contain duplicate items. The list [1, 1, 1, 1, 1]
is a perfectly valid (and sometimes actually useful!) list - which is different from the list [1, 1, 1]
because it has a different length.
In Python we can add ("append") an element to a list. We can remove ("delete") an element from a list. We can "extend" a list with another list to get a new, bigger list. We can retrieve a specific element of the list by its position. As you probably know, computers typically start counting at 0
(unlike us humans who like to start at 1
). So in the list fruits = ['Apple', 'Banana', 'Mango']
, we say that there are 3 elements but element number 0 is 'Apple', element 1 is 'Banana', and element 2 is 'Mango'. We call this "indexing". So in Python you use syntax like fruits[0]
to get the fruit at index 0. Python also allows you to index elements backwards (i.e. from right to left). So you can say fruits[-1]
to get the last element (regardless of how many there are) - in this case the 'Mango'. You can get a 'Banana' at fruits[-2]
and so on.
Get good at handling lists. You will be glad you did. Learn how to slice and dice them ("slicing" is an actual Python list operation - while "dicing" isn't (yet).) Learn how to manipulate the elements in a list - one by one, or in groups. How to make new lists from existing lists and how to modify a list.
It is important to note that lists can be modified. For example, we can swap the 'Banana' in our list of fruits for a 'Lemon' by saying fruits[1] = 'Lemon'
. So our list is now ['Apple', 'Lemon', 'Mango']
. Note that this is still our list of fruits
. We modified it in-place, instead of creating a new one. We can do this because lists in Python are a "mutable" data structure. In other words, it is a data structure that can be modified in-place.
There is another Python data type, very similar to lists, but with the important difference that, once defined, it can not be modified in place. It is called a tuple
. Tuples are defined like this in Python: (1, 2, 3)
. Note the use of a different kind of brackets to the ones we used for a list.
Like lists, tuples can also contain any number of elements of any data type. Unlike lists, however, tuples are "immutable". Once we define them, they are of fixed length (we can not append new elements to them, or remove elements from them) and the values of their elements can't be changed. Because of these constraints, tuples are often safer to work with and can be represented more efficiently in the computer's memory - as well as having certain other advantages. Of course, sometimes you just need the greater versatility of a list. With time and practice, you will develop an instinct on which data structure is more appropriate for your use-case, but for now a good rule of thumb is: stick to using tuples, unless you're sure you actually need a list.
Yet another very powerful type of collection is the "set" - defined in Python with yet another type of brackets: {1, 2, 3}
. Unlike lists and tuples, sets are not ordered. So {'p', 'a', 't'}
and {'t', 'a', 'p'}
are the same set. Importantly, as in mathematics, sets only contain unique elements, which means that each element can only exist once in the set. So if you have the set {1, 2, 3}
and you add another integer 2
to it, you're still left with the same set {1, 2, 3}
, because 2
is already in there. Like lists, sets are mutable - you can add and remove elements from them. Python also makes it easy to perform mathematical operations on sets - like finding the union of two sets (all elements in the first set plus all elements in the second); the intersection of two sets (all elements that are common to both sets); the difference of two sets (all elements in one set which are not in the other); etc. In fact, if you master set logic, you will be able to write many different kinds of Python programmes - even some rather complex ones - in very elegant and concise ways. The fluent use of sets is actually one of the signs I look for when I want to hire a good Python dev.
Speaking of logic - we mentioned there is a somewhat special basic data type called "boolean" (or just bool
in Python). While it's probably the simplest data type you will encounter (it only has two values - True and False), it is also a very important data type to master. In mathematics - and in programming - there is something called "Boolean logic", which starts with these two values (True and False, or in mathematics just 1 and 0) and builds up a rather sophisticated body of knowledge around the different ways these can be combined. Nearly all modern programming languages rely very heavily on the use of Boolean logic, so do yourself a favour and get comfortable with your "and"s, "or"s and "not"s.
Finally, as you are beginning to write some simple Python programmes, it can get a bit boring to just assign values to variables and juggle them around, without having some basic tools for interacting with the user of the programme. There are many ways to do this in Python, but for starters, see what you can learn about print()
and input()
. I use brackets after the names print
and input
to indicate that these are Python functions. We'll talk a lot more about the very important concept of functions soon, but for now you can just think of print()
as a way to show a certain piece of data (or the value of a variable) to the user, and input()
as a way to ask the user for a new value you wish to assign to a variable.
Here are some questions and topics to research and discuss:
- What are the various operations that can be performed on lists (and their elements)?
- How does list slicing work in Python? What are all the different things you can do with slicing? (EXTRA CREDIT: can you figure out how to get all the elements of a list in reverse order just by using slicing notation?)
- EXTRA CREDIT: What are the limitations on what kinds of values can be placed in a set? For example, can you include a whole list as one of the elements of a set? Why or why not? What happens in Python when you try to do that?
- How can you turn a list into a tuple or a set? Can you freely convert between any two of these?
- Thinking about Boolean logic, what can you learn about the concept of "Truth value" in Python? What are some examples of things that are "truthy" in Python? What are some examples of things that are "falsy"?
- If you have a variable
x
, which has been assigned some value, how can you ask Python what the data type ofx
is? - EXTRA CREDIT: What is the
Enum
data type in Python? Is it a mutable or immutable data type? When is it preferable to useEnum
s instead of any of the other types of collections we mentioned? - Go back to the programme you wrote in the previous lesson, describing your character, and see if you can give your character a collection of superpowers. Can you display your character's superpowers to the user? Can you modify your programme to ask the user about their favourite superpower and add it to your character's collection - but only if they don't already have it?
In the next lesson, we will explore one more very important data structure, known by many names - "map", "look-up table", "hash table", "dictionary" - or just dict
in Python. And we'll see how we can start building more logic into our programmes, to make them do more interesting things, by learning about "conditionals" and the real-world applications of Boolean logic.