4 Powerful Python Destructuring Features

Unpacking iterable, avoid indices, omit elements and more

Anupam Chugh

Jul 12, 2020·4 min read

Photo byAlmos BechtoldonUnsplash
 
Python is the most popular programming language largely owing to its pseudo-code like syntax.
 
It has some mighty powerful features and the fairly easy learning curve makes it the first choice language for developers all over the globe.
 
While list comprehensions are still the shiniest tool, destructuring is where the power lies.
 
Destructuring assignments are a shorthand syntax for mapping one or more variables from the left-hand side to the right-hand side counterparts. It’s handy in unpacking values as we shall see shortly.

Swapping And Updating Two Or More Values

Interchanging underlying values of variables is the most basic form of destructuring and it works in the following way:

a, b = b, a

Though at a high level it may seem that both the statementsa = bandb = aare only running simultaneously, there’s actually more going on under the hood.
 
Essentially, the right-hand side is evaluated first, convertingb,ainto a tuple. Subsequently, the tuple is unpacked and assigned to the left-hand side in the order left to right.
 
Consider the following snippet that updates the values ofaandb.

a = 1  
b = 2  
a, b = a + b, a

Itwon’tgive you a value 3 for bothaandb. Instead, the value ofbafter the assignment would be 1 whileabecomes 3.
 
The destructuring assignment allows us to swap more than two variables as well:

a,b,c = c,a,b

Unpacking Tuples And Iterables

Now, from what we’ve explored in the previous section, multiple assignments are fairly straightforward in Python. We can do it in a few ways:

a = b = c = 10  
a, b = 2, 3

The latter one is a destructuring assignment that works by creating a tuple of the right-hand side.
 
So, taking a cue from it we can opt to unpack values by using a tuple on the left-hand side as shown below:

a, b = (2, 3)  
(a, b) = 2, 3

xy = 1, 2  
a, b = xy

Destructuring assignment isn’t just restricted to tuples. In fact, you could use it on lists, strings, and pretty much any iterable.

a, b = [2,3]
names = "How are you?"  
a,b,c = names.split()

Using destructuring to split a string is really powerful but you need to ensure that the number of values on the left side must exactly match the number of values on the right side to avoidValueError

Recursive unpacking to access nested elements

We can unpack nested elements from lists or tuples with the same destructuring assignment syntax.

(a, b) = ([1, 2, 3], [1, 2])
([a, b], c) = ([1, 2], 3)
[a, b] = [[1,2],[3,4]]

Trailing comma

Trailing commas are optional for two or more element tuples. In case you’re using a single element tuple or you need to unpack only one element you can use the trailing comma in the following ways:

x = (1) #prints 1
x = (1,) #prints (1,)
a, = 1,
a, = [1]
[a] = [1]
#all print a == 1
a, = [1,2]
#ValueError too many elements

While parentheses are just syntactic sugar, it’s the comma that actually tells Python that the data type is a tuple. At times trailing comma can be missed which makes[a] = myLista better bet in terms of readability.

Access Elements Without Indices

Another place where the destructuring assignment is incredibly useful is when accessing values from a list. Without destructuring, more often than not, you’d end up accessing elements using indexes which can be needless.
 
By using the destructuring syntax in theenumeratefunction below, we’re able to access elements in a way that’s more concise and easy to comprehend.

myList = ["a", "b", "c"]  

for i, element in enumerate(myList):  
print(counter, element)

By following the same approach we can destructure dictionaries into key-value pairs or a list of tuples as shown below.

listOfTuples = [(1,0),(0,1)]
for i, (p1, p2) in enumerate(listOfTuples):
      #do your magic here

Select Or Omit Certain Values

By using the * operator (introduced in Python 3), we can choose to pick an optional unknown number of elements as shown below:

*a, b = 1, 2, 3, 4
# a is [1,2,3]
#b is 4

The asterisk operator creates a new list of all but the last element and puts them ina. This is useful when you need to extract sublists in Python.
 
We can also use the asterisk operator for getting the first and last elements from a list or even packing values and pass them into a function — which helps us get rid of long parameter lists in functions.

def sum(a, b, c):
    return a + b + c

x = (1, 2, 3)
print(result(*x))

Note: Dictionary unpacking requires**.
 
On the contrary, if you’re looking to drop or ignore the value in destructuring assignments using the_syntax is the way to go.*_lets you omit an unknown number of values.

a, _ = [1, 2]
first, *_, last = "Hello"
#first is 'H'
#last is 'o'

Conclusion

So, we saw how destructuring syntax helps in swapping and multi-assignments as well as in unpacking tuples, iterable and accessing elements without indexes in a for a loop.
 
I hope you make good use of the destructuring syntax in Python.
 
That’s it for this one. Thanks for reading.

+ Recent posts