Lists vs tuples

Martin McBride, 2018-03-27
Tags list tuple mutability immutable object
Categories python language intermediate python

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[1] = 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 intent

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!

If you found this article useful, you might be interested in the book Python Quick Start or other books by the same author.


Popular tags

2d arrays abstract data type alignment and animation arc array arrays bezier curve built-in function callable object circle classes close closure cmyk colour comparison operator comprehension context context manager conversion creational pattern data types design pattern device space dictionary drawing duck typing efficiency else encryption enumerate fill filter font font style for loop function function composition function plot functools game development generativepy tutorial generator geometry gif gradient greyscale higher order function hsl html image image processing imagesurface immutable object index inner function input installing iter iterable iterator itertools l system lambda function len line linspace list list comprehension logical operator lru_cache magic method mandelbrot mandelbrot set map monad mutability named parameter numeric python numpy object open operator optional parameter or partial application path polygon positional parameter print pure function pycairo radial gradient range recipes rectangle recursion reduce rgb rotation scaling sector segment sequence singleton slice slicing sound spirograph sprite square str stream string stroke subpath symmetric encryption template text text metrics tinkerbell fractal transform translation transparency tuple turtle unpacking user space vectorisation webserver website while loop zip