Python tuples#

Before we continue with numpy, let’s briefly talk about the tuple data type in python.

Copyright notice: large parts of this lecture are copied from the py4e lecture on tuples (CC-BY - Charles R. Severance).

What is a tuple?#

A tuple is a sequence of values much like a list: the values stored in a tuple can be any type, and they are indexed by integers. Syntactically, a tuple is a comma-separated list of values:

t = 'a', 'b', 'c', 'd', 'e'

Although it is not necessary, it is common to enclose tuples in parentheses to help us quickly identify tuples when we look at Python code:

t = ('a', 'b', 'c', 'd', 'e')

To create a tuple with a single element, you have to include the final comma:

t1 = ('a',)
type(t1)
tuple

Another way to construct a tuple is the built-in function tuple. With no argument, it creates an empty tuple:

t = tuple()
t
()

“Fun” fact: the word “tuple” comes from the names given to sequences of numbers of varying lengths: single, double, triple, quadruple, quintuple, sextuple, septuple, etc. It is therefore also pronounced like these words.

How are tuples different than lists?#

Tuples behave like lists in many ways:

t = tuple('sequence')
l = list('sequence')
t, l
(('s', 'e', 'q', 'u', 'e', 'n', 'c', 'e'),
 ['s', 'e', 'q', 'u', 'e', 'n', 'c', 'e'])
t[1], l[1]
('e', 'e')
for element in t:
    print(element)
s
e
q
u
e
n
c
e

The important difference is that tuples are immutable. This means that, like strings, they can’t be changed after being created:

# No problem here
l[1] = 'iiiii'
l
['s', 'iiiii', 'q', 'u', 'e', 'n', 'c', 'e']
# This wont work
t[1] = 'iiiii'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[9], line 2
      1 # This wont work
----> 2 t[1] = 'iiiii'

TypeError: 'tuple' object does not support item assignment

This property makes them useful in certain situations, as we will see when we will learn about dictionaries.

Tuple assignment#

One of the unique syntactic features of the Python language is the ability to have a tuple on the left side of an assignment statement. This allows you to assign more than one variable at a time when the left side is a sequence.

In this example we have a two-element list (which is a sequence) and assign the first and second elements of the sequence to the variables x and y in a single statement:

m = ['have', 'fun']
x, y = m
print(x)
print(y)
have
fun

This is called “unpacking”, and it is quite useful. It is not magic, Python roughly translates the tuple assignment syntax to be the following:

m = ['have', 'fun']
x = m[0]
y = m[1]

Stylistically when we use a tuple on the left side of the assignment statement, we omit the parentheses, but the following is an equally valid syntax:

(x, y) = m

A particularly clever application of tuple assignment allows us to swap the values of two variables in a single statement:

(y, x) = (x, y)
print(x)
print(y)
fun
have

The number of variables on the left and the number of values on the right must be the same:

# This will fail
a, b = 1, 2, 3
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[14], line 2
      1 # This will fail
----> 2 a, b = 1, 2, 3

ValueError: too many values to unpack (expected 2)

Tuples and functions with multiple outputs#

Tuples are used to return more than one variable from a function. For example:

def split_email_address(email):
    """Splits an email address in username and domain.

    Parameters
    ----------
    email : str
        the email string

    Returns
    -------
    (username, domain): tuple of strings
    """
    return tuple(email.split('@'))

split_email_address('john.doe@uibk.ac.at')
('john.doe', 'uibk.ac.at')

Bonus: sequence comprehension#

In your searches, you may already have encountered the following syntax:

l = [i for i in range(10) if i % 2 == 1]
l
[1, 3, 5, 7, 9]

This is the “one-liner” equivalent of:

l = []
for i in range(10):
    if i % 2 == 1:
        l.append(i)
l
[1, 3, 5, 7, 9]

This is called a “list comprehension” and also works with tuples:

tuple(i for i in range(10) if i % 2 == 1)
(1, 3, 5, 7, 9)

Learning checklist#