What are tuples in Python?

In Python, tuples are a sequence data type, very similar to lists.

We create tuples by using a comma-separated list of values:

# A dummy tuple
t = 1, 2, 3

# We usually use parentheses when creating a tuple
person = ('John', 'Doe')

# Tuples can contain mixed data types (even nested tuples)
city = (
	'New York',
	'8500000',
	('The Bronx', 'Brooklyn', 'Manhattan', 'Queens', 'Staten Island')
)

movie = ('Taxi Driver', 'Martin Scorsese', 1976)

You might ask, if tuples are created as comma-separated, how do you create a single-element (singleton) tuple? It's simple:

# Leave a trailing comma
t = 1, 

# You need the trailing comma even when using parentheses
t = (1, )

# Without the comma, this does not create a tuple
t = (1)

To access an element of a tuple, we use indexing, just like we would do with a list:

city = (
	'New York',
	'8500000',
	('The Bronx', 'Brooklyn', 'Manhattan', 'Queens', 'Staten Island')
)

print(city[0])
print(city[1])
print(city[2])
print(city[2][1])
New York
8500000
('The Bronx', 'Brooklyn', 'Manhattan', 'Queens', 'Staten Island')
Brooklyn

Note that tuples implement all of the common sequence operations, such as:

  • x in s - check if x is equal to any elements in s
  • x not in s  - check if x is not equal to any elements in s
  • s + t - return the concatenation of s and t
  • s[i] - simple indexing, returns the i-th element of the tuple
  • s[i:j] , s[i:j:k] - slicing
  • len(s) - number of elements in s
  • min(s) , max(s) - the smallest/the largest value in s

Why use a tuple instead of a list?

Unlike lists, tuples are immutable - once created, you can not assign values to individual elements of the tuple or add new elements to it.

So why do tuples exist at all? There are several reasons:

  • Being immutable, tuples are hashable, ie. can be used as dict keys
  • Being immutable, tuples allow for runtime optimizaitions when storing, comparing, copying and assigning them to variables
  • Tuples often contain heterogeneous data, are returned as results of functions, and are often accessed by unpacking (see below)

Tuple unpacking

We have seen earlier how we can create a tuple by packing together a list of values. We did it simply by listing several variables using commas:

t = 'a', 10, 100.0

We can also unpack a tuple (or any sequence, for that matter). For example:

personal_id, name, last_name = ('123456', 'John', 'Doe')

The result of this assignment is equivalent to the following:

personal_id = '123456'
name = 'John'
last_name = 'Doe'

The real convenience of tuple unpacking is obvious when we use it to unpack tuples that are returned from a function:

import random

# A function that returns a tuple
def random_movie():
	# A list of movies represented as tuples (title, director)
	movies = [
		('Reservoir Dogs', 'Quentin Tarantino'),
		('Pulp Fiction', 'Quentin Tarantino'),
		('Jackie Brown', 'Quentin Tarantino'),
		('Kill Bill: Vol. 1', 'Quentin Tarantino'),
		('Kill Bill: Vol. 2', 'Quentin Tarantino'),
		('Taxi Driver', 'Martin Scorsese'),
		('Goodfellas', 'Martin Scorsese'),
		('The Age of Innocence', 'Martin Scorsese'),
		('Mean Streets', 'Martin Scorsese')
	]

	return random.choice(movies)

if __name__ == '__main__':
	# Here we do tuple unpacking
	title, director = random_movie()

	print('Title:', title)
	print('Director:', director)

We frequently use tuple unpacking to make code more readable. Consider the following example:

import random

movies = [
	('Reservoir Dogs', 'Quentin Tarantino', 1992),
	('Pulp Fiction', 'Quentin Tarantino', 1994),
	('Jackie Brown', 'Quentin Tarantino', 1997),
	('Kill Bill: Vol. 1', 'Quentin Tarantino', 2003),
	('Kill Bill: Vol. 2', 'Quentin Tarantino', 2004),
	('Taxi Driver', 'Martin Scorsese', 1976),
	('Goodfellas', 'Martin Scorsese', 1990),
	('The Age of Innocence', 'Martin Scorsese', 1993),
	('Mean Streets', 'Martin Scorsese', 1973)
]

if __name__ == '__main__':
	for movie in movies:
		print(f'{movie[0]}, year: {movie[2]}')

We can rewrite the loop in the following way, taking advantage of tuple unpacking:

if __name__ == '__main__':
	for (title, director, year) in movies:
		print(f'{title}, year: {year}')

Can a Python tuple contain different data types?

Yes.

You can mix as many data types as you want inside of a tuple. A tuple can even contain other tuples or complex data structures:

t = ('abc', 1, ('a', 'b'), [1.0, 2.0, 3.0])