Skip to content
Home » Extended Sequence Unpacking in Python

Extended Sequence Unpacking in Python

Spread the love

Today we’ll be talking about extended sequence unpacking.

extended sequence unpacking

We’ll see how to assign the elements of a sequence to multiple variables in one go. We’ll have a look at basic sequence assignment as a starting point.

Basic Sequence Assignment

You can assign the elements of a sequence to multiple variables. The condition that must be met is that the number of the elements must be equal to the number of the variables:

In case of tuple assignment, the parentheses may be skipped:

>>> a, b, c, d = 1, 2, 3, 4  
>>> a
1
>>> b
2
>>> c
3
>>> d
4

If there are different numbers on both sides of the assignment operator, we get an error:

>>> x, y, z = 1, 2, 3, 4, 5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 3)

Here are some more examples of sequence assignments:

– tuple assignment with parentheses:

>>> a, b, c = ('one', 'two', 'three') 
>>> a
'one'
>>> b
'two'
>>> c
'three' 

– list assignment:

>>> p, q, r, s, t = [True, True, False, False, True]
>>> p, t
(True, True)

– string assignment:

>>> letter1, letter2, letter3, letter4, letter5 = 'hello'
>>> letter1, letter3, letter5
('h', 'l', 'o')

– another string assignment:

>>> animal = 'cat'
>>> a, b, c = animal
>>> a
'c'
>>> b
'a'
>>> c
't'

We can assign to nested sequences as well:

>>> (a, b, c), d = 'dog', 'cat'
>>> a, b, c, d
('d', 'o', 'g', 'cat')

>>> a, (b, c, d), e = 'dog', 'cat', 'mouse'
>>> a, b, c, d, e
('dog', 'c', 'a', 't', 'mouse')

It also works with ranges:

>>> a, b, c, d = range(4)
>>> a, b, c, d
(0, 1, 2, 3)

We can also assign to loop variables provided the patterns match:

>>> for (a, (b, c)) in [(1, (2, 3)), (4, (5, 6))]:
...     print(f"a = {a}   b = {b}   c = {c}")
... 
a = 1   b = 2   c = 3
a = 4   b = 5   c = 6

Your Panda3D Magazine

Make Awesome Games and Other 3D Apps

with Panda3D and Blender using Python.

Cool stuff, easy to follow articles.

Get the magazine here (PDF).

Extended Sequence Unpacking

And now, after this lengthy introduction, let’s have a look at the actual topic of this article, extended sequence unpacking.

If we use the star operator, it’s possible to have different numbers of elements on each side of the assignment operator. The starred variable will be assigned a list with all the leftovers that were not assigned to the other variables. There may be only one starred variable:

Here’s a simple example:

>>> animals = ['monkey', 'snake', 'rhino', 'frog', 'slug']
>>> first, *rest = animals
>>> first, rest
('monkey', ['snake', 'rhino', 'frog', 'slug'])

or the other way around:

>>> *most, last = animals
>>> most, last
(['monkey', 'snake', 'rhino', 'frog'], 'slug')

We can even assign the elements from the middle:

>>> first, *middle3, last = animals
>>> first, middle3, last
('monkey', ['snake', 'rhino', 'frog'], 'slug')

or:

>>> first, second, *next2, last = animals
>>> first, second, next2, last
('monkey', 'snake', ['rhino', 'frog'], 'slug')

In all the above examples we were using the animals list, but it may be any sequence:

– tuples:

>>> grades = ('A', 'B', 'C', 'D', 'E', 'F')
>>> best_grade, *other_grades, worst_grade = grades
>>> best_grade, other_grades, worst_grade
('A', ['B', 'C', 'D', 'E'], 'F')

– strings:

>>> word = 'unbelievable'
>>> first, *middle, last_but_one, last = word
>>> first, last_but_one, last
('u', 'l', 'e')
>>> middle
['n', 'b', 'e', 'l', 'i', 'e', 'v', 'a', 'b']

– ranges:

>>> a, *b, c, d = range(20)
>>> a, b, c, d
(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], 18, 19)

Most of this can be achieved with slicing. The difference is that in slicing you obtain an object of the same type.  So, if you slice a string, you obtain a string, if you slice a list, you obtain a list, and the same with tuples. Using extended sequence unpacking you always obtain a list.

Here’s how you can use it in loops:

>>> for a, *b, c in ("&music&", "&art&", "&science&"):
...     print(b)
... 
['m', 'u', 's', 'i', 'c']
['a', 'r', 't']
['s', 'c', 'i', 'e', 'n', 'c', 'e']

Python Jumpstart Course

Learn the basics of Python, including OOP.

with lots of exercises, easy to follow

The course is available on Udemy.

Some Special Cases

Here are some special cases to note:

1) If the number of elements to unpack is the same as the number of variables to assign to, the starred variable will be assigned a list anyway:

>>> name = "Jenny"
>>> a, b, *c, d, e = name
>>> a, b, c, d, e
('J', 'e', ['n'], 'n', 'y')

2) If there is nothing left to collect in the list with the leftovers, an empty list is assigned to the starred variable:

>>> a, b, *c, d, e, f = name
>>> a, b, c, d, e, f
('J', 'e', [], 'n', 'n', 'y')

3) The star assignment target on the left must be in a list or tuple. Otherwise we get an error:

>>> nums = [1, 2, 3, 4, 5]
>>> *a = nums
  File "<stdin>", line 1
SyntaxError: starred assignment target must be in a list or tuple

Let it be in a list:

>>> [*a] = nums
>>> a
[1, 2, 3, 4, 5]

Now let it be in a one-element tuple:

>>> (*a,) = nums
>>> a
[1, 2, 3, 4, 5]

The parentheses may be skipped, but not the comma:

>>> *a, = nums
>>> a
[1, 2, 3, 4, 5]

As mentioned before, we can achieve practically the same using indexing and slicing, but extended sequence unpacking is usually simpler to code, so why not use it if it’s out there for us to use?

Blender Jumpstart Course

Learn the basics of 3D modeling in Blender.

step-by-step, easy to follow, visually rich

The course is available on Udemy and on Skillshare.

Here you can watch the video version:


Spread the love

Leave a Reply