When you start learning Python, it isn’t too long before you encounter lists.
Then at some point you will meet tuples. These are strange objects which are quite a lot like lists, and yet you will probably get the impression that they are not meant to be used in quite the same way. In this article, I hope to shed some light on how tuples are intended to be used.
The technical differences
There are very few actual differences between lists and tuples. One obvious difference is that they are declared in different ways:
k = [1, 2, 3] #list t = (1, 2, 3) #tuple
The main difference is that tuples are immutable – once you have created a tuple, you cannot change it. You can’t add elements, remove elements, reorder the elements, or change the value of any element. For example if you try to alter the value of an element in a tuple, it will give an error:
t = 5 # TypeError: 'tuple' object does not support item assignment
If you look at built-in methods of lists, you will see that many of them don’t exist for tuples. Anything which doesn’t alter the tuple (such as find()) is OK, but methods such as sort() simply don’t exist for a tuple.
A final difference is that tuples support packing and unpacking notation. You can create a tuple without the brackets (packing), and you can extract the elements to variables in one line (unpacking):
t = 1, 2, 3 #packing a, b, c = t #unpacking
You might also hear it said that tuples are more efficient, because they do not need to support mutability. This may be true in some limited cases, but it won’t usually make a noticeable difference to your code. If you scatter tuples around your code in the hope of making it run faster, you are going to be disappointed. That really isn’t the point of them
The original purpose of tuples was to be used to hold records. What is a record? Well if you look at a typical spreadsheet (or database) each row will probably be a record. For example, if the spread sheet held the details of the members of your local Badminton society, the columns might be title, first name, last name, phone number. One row would contain the details of a member, eg
('Mr', 'John', 'Smith' '0123 4567')
This would be a prime candidate for using a tuple, rather than a list, because the items are related, that is they all refer to different properties the same person, object or whatever.
On the other hand, if you took one of the columns, for example the list of everyone’s surnames, it would be exactly that – a list (not a tuple). The names don’t all relate to the same object. They are all names of members of the Badminton club, but they are not really properties of the club.
Now quite often we might want to return a record from a function. Which is were the packing syntax comes in handy. Suppose we have a function mousepos(), which returns the x and y coordinates of the current mouse cursor. If the coordinates are held in variables x and y, we can create a tuple on the fly and return it using packing:
def mousepos(): ... return x, y
And when we call the function we can assign the result to two variables x and y using unpacking:
x, y = mousepos()
This gives the helpful illusion that our function has returned two values (which of course it has, but with the help of an invisible tuple along the way).
Spotting a tuple
So when exactly should you use a tuple rather than a list? Here are some indicators that you might need a tuple:
- The elements each represent a different property of a single object
- The number of elements if fixed (for example, an x, y coordinate always has two elements)
- The elements may be different types – a heterogeneous list
Here are cases where you might be better with a list:
- The items do not form a record, ie they are not related to a single object
- The number of elements can vary, for example the number of names in the list of badsoc members could be anything, it depends on the current size of the club.
- The elements will often (but not always) be the same type – a homogeneous list
Now to muddy the waters a little, we have the separate fact that tuples are immutable. This means that tuples can be used as an alternative to lists in a couple other circumstances:
- If you pass a list into a function, the function might change the list. This might be the intended behaviour, which is fine, but if it happen unexpectedly it can cause bugs. Sometimes, if you have a list which should never change, creating it as a tuple rather than a list can be safer.
- If you are using dictionaries, you can use tuples as keys, but you can’t use lists as keys. The reason is to do with creating hash values to search keys efficiently, but that is another topic.
In summary, there are rules about when to use lists or tuples, but in many real life situations it is not completely clear cut and can be a judgement call. In fact, even if you get it completely wrong, your code will still work. Still, it is always nice to know the right way to do it!