Lists vs tuples

By 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

Immutability

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!

See also

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

Join the PythonInformer Newsletter

Sign up using this form to receive an email when new content is added:

Popular tags

2d arrays abstract data type alignment and angle animation arc array arrays bar chart bar style behavioural pattern bezier curve built-in function callable object chain circle classes clipping close closure cmyk colour combinations comparison operator comprehension context context manager conversion count creational pattern data science data types decorator design pattern device space dictionary drawing duck typing efficiency ellipse else encryption enumerate fill filter font font style for loop formula function function composition function plot functools game development generativepy tutorial generator geometry gif global variable gradient greyscale higher order function hsl html image image processing imagesurface immutable object in operator index inner function input installing iter iterable iterator itertools join l system lambda function latex len lerp line line plot line style linear gradient linspace list list comprehension logical operator lru_cache magic method mandelbrot mandelbrot set map marker style matplotlib monad mutability named parameter numeric python numpy object open operator optimisation optional parameter or pandas partial application path pattern permutations pie chart pil pillow polygon pong positional parameter print product programming paradigms programming techniques pure function python standard library radial gradient range recipes rectangle recursion reduce regular polygon repeat rgb rotation roundrect scaling scatter plot scipy sector segment sequence setup shape singleton slice slicing sound spirograph sprite square str stream string stroke structural pattern subpath symmetric encryption template tex text text metrics tinkerbell fractal transform translation transparency triangle truthy value tuple turtle unpacking user space vectorisation webserver website while loop zip zip_longest