Tuples

Published

2023-08-01

Tuples

A tuple? What’s a tuple? A tuple is an immutable sequence of objects.

Like lists they allow for indexed access of elements. Like lists they may contain any arbitrary type of Python object (int, float, bool, str, etc.). Unlike lists they are immutable, meaning that once created they cannot change. You’ll see that this property can be desirable in certain contexts.

How do we write a tuple?

The crucial thing in writing a tuple is commas—we separate elements of a tuple with commas—but it’s conventional to write them with parentheses as well.

Here are some examples:

>>> coordinates = 0.378, 0.911
>>> coordinates
(0.378, 0.911)
>>> coordinates = (1.452, 0.872)
>>> coordinates
(1.452, 0.872)

We can create a tuple with a single element with a comma, with or without parentheses.

>>> singleton = 5,
>>> singleton
(5,)
>>> singleton = ('Hovercraft',)
>>> singleton
('Hovercraft',)

Notice that it’s the comma that’s crucial.

>>> (5)
5
>>> ('Hovercraft')
'Hovercraft'

We can create an empty tuple, thus:

>>> empty = ()
>>> empty
()

In this case, no comma is needed.

Accessing elements in a tuple

As with lists, we can access the elements of a tuple with integer indices.

>>> t = ('cheese', 42, True, -1.0)
>>> t[0]
'cheese'
>>> t[1]
42
>>> t[2]
True
>>> t[3]
-1.0

Just like lists, we can access the last element by providing -1 as an index.

>>> t[-1]
-1.0

Finding the number of elements in a tuple

As with lists, we can get the number of elements in a tuple with len().

>>> t = ('cheese', 42, True, -1.0)
>>> len(t)
4

Why would we use tuples instead of lists?

First, there are cases in which we want immutability. Lists are a dynamic data structure. Tuples on the other hand are well-suited to static data.

As one example, say we’re doing some geospatial tracking or analysis. We might use tuples to hold the coordinates of some location—the latitude and longitude. A tuple is appropriate in this case.

>>> (44.4783021, -73.1985849)

Clearly a list is not appropriate: we’d never want to append elements or remove elements from latitude and longitude, and coordinates like this belong together—they form a pair.

Another case would be records retrieved from some kind of database.

>>> student_record = ('Porcupine', 'Egbert', 'eporcupi@uvm.edu', 
....                  3.21, 'sophomore')

Another reason that tuples are preferred in many contexts is that creating a tuple is more efficient than creating a list. So, for example, if you’re reading many records from a database into Python objects, using tuples will be faster. However, the difference is small, and could only become a factor if handling many records (think millions).

You say tuples are immutable. Prove it.

Just try modifying a tuple. Say we have the tuple (1, 2, 3). We can read individual elements from the tuple just like we can for lists. But unlike lists we can’t use the same approach to assign a new value to an element of the tuple.

>>> t = (1, 2, 3)
>>> t[0]
1
>>> t[0] = 51
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

There you have it: “‘tuple’ object does not support item assignment.”

What about this?

>>> t = (1, 2, 3)
>>> t = ('a', 'b', 'c')

“There!” you say, “I’ve changed the tuple!” No, you haven’t. What’s happened here is that you’ve created a new tuple, and given it the same name t.

What about a tuple that contains a list?

Tuples can contain any type of Python object—even lists. This is valid:

>>> t = ([1, 2, 3],)
>>> t
([1, 2, 3],)

Now let’s modify the list.

>>> t[0][0] = 5
>>> t
([5, 2, 3],)

Haven’t we just modified the tuple? Actually, no. The tuple contains the list (which is mutable). So we can modify the list within the tuple, but we can’t replace the list with another list.

>>> t = ([1, 2, 3],)
>>> new_list = [4, 5, 6]
>>> t[0] = new_list
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Again, the tuple is unchanged.

You may ask: What’s up with the two indices?

Say we have a list within a tuple. The list has an index within the tuple, and the elements of the list have their indices within the list. So the first index is used to retrieve the list from within the tuple, and the second is used to retrieve the element from the list.

>>> t = (['a', 'b', 'c'],)
>>> t[0]
['a', 'b', 'c']
>>> t[0][0]
'a'
>>> t[0][1]
'b'
>>> t[0][2]
'c'

Original author: Clayton Cafiero < [given name] DOT [surname] AT uvm DOT edu >

No generative AI was used in producing this material. This was written the old-fashioned way.

This material is for free use under either the GNU Free Documentation License or the Creative Commons Attribution-ShareAlike 3.0 United States License (take your pick).