Top Rated Plus on Upwork with a 100% Job Success ScoreView on Upwork
retzdev logo
logo
tech

Python: Destructuring (Packing and Unpacking)

by Jarrett Retz

October 30th, 2020

Why Pack or Unpack Values?

Python developers may unpack, or pack values to compensate for the unknown length of values in an iterable or unknown key/value pairs in a dictionary.

iterable may be either a sequence, a container that supports iteration, or an iterator object. (Python Docs)

As an example, let's say that a function named getStudentInfo() returns a list with the student information and the letter grades that the student has received in different classes.

["Taylor", "Science", "A", "B", "B", "A", "C"]

# name, major, letter grades

The function always returns the name and major, but students take a different number of classes. Thus, we can't rely on the same number of grades in the list. To handle this variability, we can unpack the values.

When you see >>> in the code examples, it means I am using Python's IDLE.

>>> def getStudentInfo():
	return ["Taylor", "Science", "A", "B", "B", "A", "C"]

>>> name, major, *grades = getStudentInfo()
>>> name
'Taylor'
>>> major
'Science'
>>> grades
['A', 'B', 'B', 'A', 'C']

This example is small, but it sheds light on how we assigned the:

  • First value in the list to the variable name
  • Second value to the variable major, and;
  • used * (an asterisk) to gather all the remaining values into a list named grades

In the next sections, let's take a look at how unpacking and packing vary across iterables, dictionaries, and functions.

Unpacking Values: Iterables vs. Dictionaries

Unfortunately, we can't unpack dictionaries in the same way that we can target variations in list values.

Let's replay our example from earlier, but use a dictionary for information instead.

>>> def getStudentInfo():
	return {"name": "Taylor","major":"Science", "Biology": "A", "Music in the Humanities": "B", "Genetics": "B"}
>>> name, major, *grades = getStudentInfo()
>>> name
'name'
>>> major
'major'
>>> grades
['Biology', 'Music in the Humanities', 'Genetics']

# We just get the keys

More Iterable Unpacking

Depending on your version of Python, you could also target your * to grab values in the middle of a list.

>>> example = ["first", "in", "be", "tween", "last"]
>>> first, *inbetween, last = example
>>> first
'first'
>>> inbetween
['in', 'be', 'tween']
>>> last
'last'

Functions: Unpacking & Packing

We can pack values and deliver them as a function's arguments, again, with a slight difference between iterables and dictionaries. Then, the function can unpack the values and use them.

Iterable

Below is an example of how we can pack values into a function that takes positional arguments.

>>> def authorInfo(name, rating):
	print(name + ' has a rating of ' + str(rating))
>>> author = ["Jarrett", 1000]
>>> authorInfo(*author)
Jarrett has a rating of 1000

The values from author are spread as the arguments in the order they appear in author.

Dictionary

We can use the same function above to demonstrate how this works with a function that takes keyword values.

First, we define the function using keyword arguments. Then, we assign the author values inside of a dictionary. However, instead of passing the author variable into the function with one * we use two **.

>>> def authorInfo(name="", rating=0):
	print(name + ' has a rating of ' + str(rating))
>>> author = {"rating": 1, "name": "Jarrett"}
>>> authorInfo(**author)
Jarrett has a rating of 1

The order of the values in the dictionary is different from the order in the function declaration, but the values are still assigned properly.

**kwargs

The **kwargs function parameter is born from unpacking an arbitrary amount of values. I see this used a lot in matplotlib​ . The graphing functions have the option to take many layout parameters that can be defined in a dictionary.

Imagine the function call matplotlib.hist(data, **kwargs). This function plots a histogram and then takes an arbitrary number of named keyword arguments. Utilizing these arguments may look like:

matplotlib.hist(data, color="blue, ls="---")

The required data parameter is passed in, but color and line-style (ls) are optional.

This was only a brief introduction to packing and unpacking values. You can read more about this Python feature in the Python Docs.

Jarrett Retz

Jarrett Retz is a freelance web application developer and blogger based out of Spokane, WA.

jarrett@retz.dev

Subscribe to get instant updates

Contact

jarrett@retz.dev

Legal

Any code contained in the articles on this site is released under the MIT license. Copyright 2024. Jarrett Retz Tech Services L.L.C. All Rights Reserved.