When I first started learning python, one of the cool things I learned was packing and unpacking of sequences like tuples. I fell in love with them that I ended up using them all the time. They were a feature I had found only in python and javascript.
Packing and unpacking, also called destructuring i.e the ability to extract multiple values from data stored in objects, has lots of techniques I have discovered over the years. I will highlight some in this post.
a. Packing and unpacking of sequences
As a convenient way to assign variables with a single line of code, automatic packing is an often used technique that can serve you well. It usually is applied to sequences like tuples, lists, and ranges. For a refresher on sequences and how they are a subset of iterables, see this post.
For example, we could automatically pack and unpack this list into three variables, x, y, and z.
We could do a similar thing with a tuple, unpacking the tuple and assigning its values.
Most often where programmers apply this automatic packing and unpacking technique is when they want to return multiple values from a function. Take this function for quotients and remainder that returns a tuple.
You can see that when the call returns the output, a tuple, is automatically packed into two variables. You get to see this often in code and this is a cool feature from python.
The packing feature has its dual companion, the unpacking feature for sequences. I highlighted one above but let me show you another with unpacking in tuples.
See how python nicely unpacks the range and assigns it immediately to the variables on the left.
One thing you need to note when packing and unpacking with sequences is that the number of variables on the left should match the number of items you want to unpack or pack on the right.
You do not only pack and unpack on the right side of the assignment operator. You can also pack and unpack on the left. Take this example.
I first assigned the first element to variable ‘a’ and then packed the remaining items in the tuple into ‘d’. Just use your creativity.
You can unpack in a for loop. Remember, for loops need an iterable. That is why unpacking can be deployed there also. Take this list of tuples and see how one can unpack the tuples in a for loop.
This technique of unpacking in a for loop is what you are doing when you call the dictionary.items() method with a syntax like this:
This technique of packing and unpacking has resulted in the tradition of simultaneous assignments in python which has come to replace the need for temporary variables when you want to swap values among two variables. For example, in the former archived way of swapping, one could do it this way:
temp = y
y = x
x = temp
This has come to be replaced with the more convenient and readable simultaneous assignment syntax that goes like this:
x, y = y, x
Don’t you just love the way python is evolving? I just adore it.
Now, packing and unpacking is not restricted to sequences. It extends to the arena of function arguments and function calls.
2. Packing and unpacking in functions
There are several techniques for packing and unpacking in functions and I will highlight some of the common ones.
a. Python argument tuple packing and unpacking
To carry out a packing of the arguments that are passed to the function, you just precede the formal parameter with an asterisk, *. Then any value or object that is passed to the function will be packed into a tuple.
Here is an example.
Because this argument packing can accept multiple types, you would be wise to assert the types you desire in your function.
Python argument tuple packing has its counterpart, python argument tuple unpacking. This is when on the calling side of the function you precede the object with an asterisk. The object would usually be a sequence or iterable. Then when the object is passed to the function it is unpacked.
Take this example:
Note that the number of formal arguments should be equal to the object when it is unpacked.
But who says we cannot do unpacking and packing at the same time. Yes, you can do packing and unpacking in function calls at the same time.
Let’s go to another data structure that is not a sequence – a dictionary.
b. Python argument dictionary packing and unpacking.
Just as you can do packing and unpacking for sequences, you can also do the same for dictionaries, but in the case of dictionaries you use double asterisks, **, to indicate that you are dealing with a key=value pair. While reading the python documentation several times, even on pylint if your IDE has pylint installed, you would find formal arguments specified as **kwargs. The **kwargs formal argument just says that the object that is passed would be packed into a dictionary.
Let’s take an example of a common case.
The keywords passed in the function call can be any number but the function will pack all of them into a dictionary that fits.
Now let’s illustrate the argument dictionary unpacking. This occurs at the opposite end, at the function call. This is when the object passed is preceded by double asterisk. This tells the function that the object, which is a dictionary, should be unpacked.
One final example.
f(**names) is just a shorthand for the explicit keyword arguments f(x=’A’, y=’A+’, z=’C’).
There are so many techniques which have sprung up from the principle of packing and unpacking iterables. If you have some you want to share which I didn’t mention, make a comment below and I will be sure to update this post.
Thanks. Happy pythoning.
No comments:
Post a Comment
Your comments here!