Readings: tuples
Contents
5.2. Readings: tuples#
5.2.1. Tuples#
Tuples, just like lists, are sequences of values. However, unlike lists, they are immutable. This means that they cannot be modified during program execution: you cannot add or remove elements or modify any of the individual items (like integers, floats, etc). Just like lists, they can have heterogenous or homogenous data. Everything enclosed in parentheses () is a tuple. Also, tuples are ordered, this means that the items in the tuple have an order defined at the time they are created, which cannot change. Some examples of tuples:
fermented_drinks = ('kombucha', 'wine')
fermented_drinks
('kombucha', 'wine')
Other examples of tuples:
tuple_1 = (1,2,3,4,5)
tuple_2 = (1, 'a', 2, 'b', 3, 'c')
empty_tuple = ()
singleton_tuple = (1, )
print(tuple_1)
print(tuple_2)
print(empty_tuple)
print(singleton_tuple)
(1, 2, 3, 4, 5)
(1, 'a', 2, 'b', 3, 'c')
()
(1,)
Note
Notice the comma (, )
after the singleton tuple. If we omitted it, then we would just have an integer and not a tuple anymore, although it would have been inside ()
. See the two exmaples below.
a = (1) # no comma after the integer
b = (1,)
print('The contents of "a" is', a, 'and its type is', type(a))
print('The contents of "b" is', b, 'and its type is', type(b))
The contents of "a" is 1 and its type is <class 'int'>
The contents of "b" is (1,) and its type is <class 'tuple'>
We can also define a tuple without using parentheses:
tuple_3 = 1,2,3,4,5,6
tuple_3
(1, 2, 3, 4, 5, 6)
5.2.1.1. Number of elements in a tuple#
Just like with lists, we can use the len()
function to find the number of elements in a tuple. For example:
fermented_drinks = ('wine', 'beer', 'kefir', 'kombucha')
len(fermented_drinks)
4
5.2.1.2. Accessing elements of a tuple#
Again, the same patterns used for accessing elements in a list can be used with tuples. Negative indexing holds here as well. All indices in Python are 0-based, so the index of the first element in a tuple is 0.
fermented_drinks[1]
'beer'
The above code will print the element at position 1
of the tuple. We can select a range of values, as well, using slicing:
print('Fermented drinks at positions 1-3:', fermented_drinks[1:4])
print('Fermented drinks until position 4:', fermented_drinks[:4])
print('Fermented drinks from position 1 until the end:', fermented_drinks[1])
Fermented drinks at positions 1-3: ('beer', 'kefir', 'kombucha')
Fermented drinks until position 4: ('wine', 'beer', 'kefir', 'kombucha')
Fermented drinks from position 1 until the end: beer
5.2.1.3. Adding/Removing elements to/from a tuple#
This is where the idea of tuples becoming immutable becomes evident. In the beginning of this section we emphasized the fact that tuples are immutable objects. This means that they cannot be modified. If this was not the case, then nothing would set them apart from lists. But what does this mean practically?
Each time we add/remove an element in/from a tuple a new tuple would be created behind the scenes. We will use the id()
function to confirm this.
5.2.1.3.1. Modifying elements of a tuple#
Since tuples are immutable we cannot modify their elements, but we can modify elements of mutable objects that a tuple may contain. For example, we can modify elements of a list that a tuple may contain but we cannot substitute the whole list with a new one. For example:
mixed_tuple = (1, 'a', [2, 'c', 'd'])
mixed_tuple[1] = 3
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[9], line 2
1 mixed_tuple = (1, 'a', [2, 'c', 'd'])
----> 2 mixed_tuple[1] = 3
TypeError: 'tuple' object does not support item assignment
The above piece of code gives a TypeError
because we are trying to modify an item from the tuple. However, we can modify the list that is the third item in mixed_tuple
:
mixed_tuple[2][0] = 3
mixed_tuple
(1, 'a', [3, 'c', 'd'])
In the code block above, we accessed the element at position 2 (i.e., the third item) of the tuple, which is a list. Next, we accessed the element at position 0 of this list and re-assigned this element from 2
to 3
. Since a list is mutable the operation was successful. Meanwhile if we try to substitute a list with another one, we are going to get a TypeError
again since we are trying to modify an element of a tuple:
mixed_tuple[2] = [1,2,3,4]
mixed_tuple
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_19188\1303170592.py in <module>
----> 1 mixed_tuple[2] = [1,2,3,4]
2 mixed_tuple
TypeError: 'tuple' object does not support item assignment
To understand this better have a look at Fig. 5.4:

Fig. 5.4 Modifying elements of a tuple#
As you can see, changes cannot happen in the memory space of the tuple, but they can happen in the memory space of elements of a tuple that are mutable. Since the tuple stores only a pointer to the memory location of the list, from the tuple’s perspective nothing changes with respect to the list as long as the memory address of the list remains the same. When we try to assign a different list to the tuple element at position 2, we are changing the pointer, since the new list will be in a different location from the existing one. This consists of making a change in the memory space of the tuple, thus it raises a TypeError
.
5.2.1.3.2. Adding elements to a tuple#
numbers_1 = (1,2,3,4)
print('ID of numbers_1 before adding new elements:', id(numbers_1))
numbers_1 += (6,8)
print('ID of numbers_1 after adding new elements:', id(numbers_1))
ID of numbers_1 before adding new elements: 140693547998192
ID of numbers_1 after adding new elements: 140693541171392
Fig. 5.5 illustrates what actually happens in memory when we try to add elements to a tuple.

Fig. 5.5 Adding elements to a tuple#
As you can see, the ID has changed, although we are referring to the same variable numbers_1
. This does not happen in any case for a list
. For example:
numbers_list_1 = [1,2,3,4]
print('ID of numbers_list_1 before adding new elements:', id(numbers_list_1))
numbers_list_1 += (6,8) # adding a tuple to a list
print('ID of numbers_list_1 after adding new elements:', id(numbers_list_1))
ID of numbers_list_1 before adding new elements: 140693548117440
ID of numbers_list_1 after adding new elements: 140693548117440
As you can see, the ID has not changed.
5.2.1.3.3. Removing elements from a tuple#
To remove values from a tuple we first need to convert the tuple to a list. Then we can remove values using one of the ways explained in Removing elements from a list. After that, we can convert the list back to a tuple. This will result in a new tuple being created.
print('Tuple at the beginning:', numbers_1)
print('ID of numbers_1 after adding new elements:', id(numbers_1))
#convert tuple to list
list_from_tuple = list(numbers_1)
#remove element 8 from list
list_from_tuple.remove(8)
#convert list back to tuple
numbers_1 = tuple(list_from_tuple)
print('Tuple after removing 8:', numbers_1)
print('ID of numbers_1 after removing 8:', id(numbers_1))
Tuple at the beginning: (1, 2, 3, 4, 6, 8)
ID of numbers_1 after adding new elements: 140693541171392
Tuple after removing 8: (1, 2, 3, 4, 6)
ID of numbers_1 after removing 8: 140693547995696
Here the creation of the new tuple object is more evident since we are using the tuple()
function to create a new tuple from a given list. You can confirm this by checking the changed IDs. In memory, the process is similar to what is depicted in Fig. 5.5, except that now we copy only the elements that we need.
5.2.1.4. Searching tuples#
There is also an index()
method for searching for specific elements in tuples. Just like in the case of lists, it will return the index of the first occurrence of the element passed as an argument to the method or ValueError
if the value we are searching for is not in the tuple.
numbers_1.index(2)
1
numbers_1.index(100) # 100 is not present in the tuple
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/var/folders/7f/7nw_x13n5q965rss_qz6061m0000gq/T/ipykernel_47389/3137910176.py in <module>
----> 1 numbers_1.index(100) # 100 is not present in the tuple
ValueError: tuple.index(x): x not in tuple
5.2.1.5. Counting elements in tuples#
By using the count()
method we can find the number of occurrences of the elements passed as an argument to the method. For example:
numbers_1.count(6)
1
Next on, we will see some methods and functions that apply to both lists and tuples.