A tuple is a sequence of immutable Python objects. Like lists, tuples are ordered collections. The primary difference between a tuple and a list is that tuples are immutable, while lists are mutable. Tuples use parentheses ()
while lists use square brackets [ ]
.
There are several advantages of using tuples over lists. Here are the main ones:
- Generally, tuples are used for heterogeneous data (different data types), whereas lists are used for homogeneous data (similar data types).
- Since tuples are immutable, iterating through a tuple is faster than iterating through a list, providing a small performance boost.
- Tuples containing immutable elements can be used as keys for dictionaries, which is not possible with lists.
- If you have data that shouldn't be modified, implementing it as a tuple ensures that it remains write-protected.
A tuple is created by placing all items (elements) inside parentheses ()
separated by commas. Parentheses are optional, but it is a good practice to use them.
A tuple can contain any number of elements, and the elements can be of different types (integer, float, list, string, etc.).
x = 1,2,3
print(type(x)) #tuple
y = (1,2,3)
print(type(y)) #tuple
Creating a tuple with a single element can be a bit tricky.
Just having one element inside parentheses is not enough. To indicate it's a tuple, a comma must be added.
x = 1,
print(type(x)) #tuple
y = (1,)
print(type(y)) #tuple
The elements of a tuple have a defined order, just like a list. Tuple indices are zero-based, so the first element of a non-empty tuple is always accessible as a_tuple[0]
.
Negative indices count from the end of the tuple, just like lists.
c = ("Python","PHP","JavaScript")
print(c[-1]) #JavaScript
Slicing works the same way as it does for lists. Slicing a list creates a new list; slicing a tuple creates a new tuple.
c = ("Dublin","Cork","Waterford","Kilkelly","Drogheda")
print(c[1:3]) #('Cork', 'Waterford')
print(type(c)) #<class 'tuple'>
The biggest difference between tuples and lists is that tuples are immutable. Technically, tuples have no methods that allow modification. For example, methods like append()
, extend()
, insert()
, remove()
, and pop()
found in lists do not exist for tuples. However, you can slice a tuple (because it creates a new tuple) and check if a tuple contains a specific value (because this operation does not modify the tuple).
You cannot add elements to a tuple. Tuples do not have an append()
or extend()
method.
You cannot remove elements from a tuple. Tuples do not have a remove()
or pop()
method.
You can find elements in a tuple since this does not modify it.
c = ("Dublin","Cork","Waterford","Kilkelly","Drogheda")
print(c.index("Dublin")) #0
print(c.count("Cork")) #1
You can use the in
operator to check if an element exists within a tuple.
cities = ["Dublin", "Cork", "Waterford", "Kilkelly", "Drogheda"]
print("Dublin" in cities) #True
print("Galway" in cities) #False
print("Galway" not in cities) #True
Tuples are faster than lists. If you are defining a constant set of values and will only iterate through it, use a tuple instead of a list.
Some tuples can be used as dictionary keys (especially tuples containing immutable values like strings, numbers, and other tuples). Lists can never be used as dictionary keys because they are mutable.
You can create a tuple from any iterable:
list_1 = [1, 2, 3]
set_1 = {1, 2, 3}
a = tuple(list_1)
b = tuple(set_1)
print(type(a))
print(type(b))
Destructuring Tuples
In Python, tuple destructuring (also known as tuple unpacking) allows you to assign the values of a tuple (or any iterable) to multiple variables in a single line. Here's how it works:
# A tuple with 3 elements
my_tuple = (1, 2, 3)
# Unpacking tuple elements into variables
a, b, c = my_tuple
print(a) # Output: 1
print(b) # Output: 2
print(c) # Output: 3
You can use an underscore _
to ignore specific values during unpacking.
my_tuple = (1, 2, 3, 4)
# Ignore the 2nd and 4th values
a, _, b, _ = my_tuple
print(a) # Output: 1
print(b) # Output: 3
Using the *
operator during unpacking, you can capture multiple elements of a tuple into a list.
my_tuple = (1, 2, 3, 4, 5)
# Assign the first value to 'a', the last to 'c', and the rest to 'b'
a, *b, c = my_tuple
print(a) # Output: 1
print(b) # Output: [2, 3, 4]
print(c) # Output: 5
Functions
max(iterable, *, key=None)
Returns the largest item in an iterable or the largest of two or more arguments.
min(iterable, *, key=None)
Returns the smallest item in an iterable or the smallest of two or more arguments.
sum(iterable, /, start=0)
Adds start
and the items of an iterable
from left to right and returns the total. The items of the iterable
are typically numbers, and the starting value cannot be a string.
Tuple Immutability: Why It Matters
Unlike lists, tuples cannot be modified after creation. This immutability provides performance benefits and ensures data integrity.
tuple_values = (1, 2, 3)
tuple_values[0] = 100 # TypeError: 'tuple' object does not support item assignment
However, if a tuple contains mutable objects (like lists), the objects themselves can be changed:
mutable_inside_tuple = ([1, 2, 3], "hello")
mutable_inside_tuple[0].append(4)
print(mutable_inside_tuple) # ([1, 2, 3, 4], 'hello')
Named Tuples
Named tuples are lightweight object types that are easy to create. Instances of named tuples can be accessed using object-like variable references or standard tuple syntax. They are similar to struct
or other common record types but are immutable.
For example, representing a point as a tuple (x, y)
is common. This results in code like:
pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)
from math import sqrt
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
print(line_length)
Using named tuples makes the code more readable:
from collections import namedtuple
Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)
from math import sqrt
line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)
print(line_length)
However, named tuples are still backward-compatible with regular tuples, so the following code will also work:
from collections import namedtuple
Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)
from math import sqrt
# Using index-based access
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
# Using tuple unpacking
x1, y1 = pt1
Another example:
from collections import namedtuple
Capital = namedtuple('Capital', 'city country')
c = Capital('Tokyo', 'Japan')
print(f"{c.city} is the capital of {c.country}")
city, country = c
print(f"{city} is the capital of {country}")
Conclusion
Tuples and named tuples are powerful, efficient data structures in Python. Tuples provide an immutable, lightweight alternative to lists, while named tuples enhance readability with attribute-based access. Whether you're working with structured data, function return values, or dictionary keys, understanding when and how to use these structures will improve your Python code quality and performance.