Sign in to your Python Morsels account to save your screencast settings.
Don't have an account yet? Sign up here.
Let's talk about extended iterable unpacking.
Tuple unpacking is great when you know the size of the iterable you're unpacking.
For example, here we're unpacking a three-item tuple (called coordinates) into three variables:
>>> coordinates = (3, 4, 5)
>>> x, y, z = coordinates
But what if we don't know the size of the iterable we're unpacking?
Here we're unpacking a list of many numbers into three variables:
>>> numbers = [2, 1, 3, 4, 7, 11, 18]
>>> first, second, rest = numbers
What do you think we'll get from this unpacking?
What will first, second, and rest be after this unpacking?
>>> first, second, rest = numbers
It turns out we get an error when we try to unpack numbers into three variables:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 3)
The number of variables we're unpacking into has to be the same as the number of items in the iterable we're unpacking.
By unpacking into three variables we were implicitly asserting that there are three items in numbers, but there are more than three items in numbers so our unpacking failed.
Since we're working with a list here we could get around this by slicing our list. We could slice this list twice to get the first two items and then everything after those items and put those in a tuple and then use deep unpacking:
>>> numbers = [2, 1, 3, 4, 7, 11, 18]
>>> (first, second), rest = numbers[:2], numbers[2:]
And this works: we end up with first and second pointing to the first two items and rest pointing to the remaining values:
>>> first
2
>>> second
1
>>> rest
[3, 4, 7, 11, 18]
But there's a better way to do this; instead we can use extended iterable unpacking.
Extended iterable unpacking involves using Python's prefix * operator:
>>> numbers = [2, 1, 3, 4, 7, 11, 18]
>>> first, second, *rest = numbers
That * allows us to capture the remaining values into a list:
>>> rest
[3, 4, 7, 11, 18]
Python always captures those remaining values into a list; even if the iterable we're unpacking isn't a list.
This * syntax is pretty nifty, but what are the limitations of it?
Could we put a * at the beginning of our tuple unpacking?
What's your guess?
>>> numbers = [2, 1, 3, 4, 7, 11, 18]
>>> *first, last = numbers
This actually works.
Python captured everything but the last item into our first variable:
>>> first
[2, 1, 3, 4, 7, 11]
>>> last
18
Could we put the * in the middle of our tuple unpacking?
>>> numbers = [2, 1, 3, 4, 7, 11, 18]
>>> first, second, *middle, last = numbers
This works as well.
That middle variable includes everything except the first two values and the last value:
>>> middle
[3, 4, 7, 11]
Could we use two stars (*) in tuple unpacking?
>>> numbers = [2, 1, 3, 4, 7, 11, 18]
>>> a, *b, *c, d = numbers
We can't.
You can only use one * in tuple unpacking:
>>> a, *b, *c, d = numbers
File "<stdin>", line 1
SyntaxError: multiple starred expressions in assignment
As long as there's just one * operator, Python will figure out what you meant.
If something is important, it deserves a name.
Tuple unpacking is great when you're trying to get rid of hard-coded indexes:
coordinates = (3, 4, 5)
x = coordinates[0]
y = coordinates[1]
z = coordinates[2]
And give names to things instead:
coordinates = (3, 4, 5)
x, y, z = coordinates
But you can also sometimes use tuple unpacking to get rid of hard-coded slices:
numbers = [2, 1, 3, 4, 7, 11, 18]
first = numbers[0]
rest = numbers[1:]
By using a * operator in tuple unpacking to capture the remaining values as you're unpacking:
numbers = [2, 1, 3, 4, 7, 11, 18]
first, *rest = numbers
So tuple unpacking is great when you know the size of the iterable that you're unpacking.
But if you don't know the size of the iterable you're unpacking and you'd like to capture the remaining values into a list you can use extended iterable unpacking by putting a star (*) before the variable that's supposed to capture those remaining values.
Need to fill-in gaps in your Python skills?
Sign up for my Python newsletter where I share one of my favorite Python tips every week.
It's tempting to reach for indexes when working with tuples, lists, and other sequences, but if we know the shape of the tuple we're working with, we can unpack it instead.
Tuple unpacking (aka "multiple assignment" or "iterable unpacking") is often underutilized by new Python programmers.
To track your progress on this Python Morsels topic trail, sign in or sign up.
Sign in to your Python Morsels account to track your progress.
Don't have an account yet? Sign up here.