Sequence unpacking

Published

2023-07-31

Sequence unpacking

Python provides us with an elegant syntax for unpacking the individual elements of a sequence as separate variables. We call this unpacking.

>>> x, y = (3.945, 7.002)
>>> x
3.945
>>> y
7.002

Here, each element in the tuple on the right-hand side is assigned to a matching variable on the left-hand side.

>>> x = (2,)
>>> x
2
>>> x, y, z = ('a', 'b', 'c')
>>> x
'a'
>>> y
'b'
>>> z
'c'

This works with tuples of any size!

a, b, c, d, e = ('Hello', 5, [1, 2, 3], 'Chocolate', 2022)

However, the number of variables on the left-hand side must match the number of elements in the tuple on the right-hand side. If they don’t match, we get an error, either ValueError: too many values to unpack or ValueError: not enough values to unpack.

Tuple unpacking is particularly useful by:

  • allowing for more concise and readable code by assigning multiple values to variables on a single line,
  • allowing for multiple values to be returned by a function,
  • making it easier to swap variable values (more on this shortly).

Can we unpack lists too?

Yup. We can unpack lists the same way.

x, y = [1, 2]

But this isn’t used as much as tuple unpacking. Can you think why this may be so?

The reason is that lists are dynamic, and we may not know at runtime how many elements we have to unpack. This scenario occurs less often with tuples, since they are immutable, and once created, we know how many elements they have.

What if we want to unpack but we don’t care about certain elements in the sequence?

Let’s say we want the convenience of sequence unpacking, but on the right-hand side we have a tuple or a function which returns a tuple, and we don’t care about some element in the tuple. In cases like this, we often use the variable name _ to signify “I don’t really care about this value”.

Examples:

>>> _, lon = (44.318393, -72.885126)  # don't care about latitude 

or

>>> lat, _ = (44.318393, -72.885126)  # don't care about longitude

This makes it clear visually that we’re only concerned with a specific value, and is preferred over names like temp, foo, junk or whatever.

Occasionally, you may see code where two elements of an unpacked sequence are ignored. In these cases, it’s not unusual to see both _ and __ used as variable names to signify “I don’t care.”

Examples:

>>> _, lon, __ = (44.318393, -72.885126, 1244.498)

or

>>> lat, _, __ = (44.318393 -72.8851266, 1244.498)

or

>>> _, __, elevation = (44.318393, -72.8851266, 1244.498)

It is possible also to reuse _. For example, this works just fine:

>>> _, _, elevation = (44.318393, -72.8851266, 1244.498)

In this instance, Python unpacks the first element of the tuple to _, then it unpacks the second element of the tuple to _, and then it unpacks the third element to the variable elevation.

If you were to inspect the value of _ after executing the line above, you’d see it holds the value -72.8851266.

Swapping variables with tuple unpacking

In many languages, swapping variables requires a temporary variable. Let’s say we wanted to swap the values of variables a and b. In most languages we’d need to do something like this:

int a = 1
int b = 2

// now swap
int temp = a
a = b
b = temp

This is unnecessary in Python.

a = 1
b = 2

# now swap
b, a = a, b

That’s a fun trick, eh?

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).