Unpacking With the Asterisk Operators
00:00
You are now able to use *args
and **kwargs
to define Python functions that take a varying number of input arguments. Let’s go a little deeper to understand something more about the unpacking operators.
00:11 The single and double asterisk unpacking operators were introduced in Python 2. As of the 3.5 release, they have become even more powerful, thanks to PEP 448, which you should check out if you’re interested. In short, the unpacking operators are operators that unpack the values from iterable objects in Python.
00:30
The single asterisk operator (*
) can be used on any iterable that Python provides, while the double asterisk operator (**
) can only be used on dictionaries.
00:40 Let’s start with an example. This code defines a list and then prints it to the standard output. Note how the list is printed along with the corresponding brackets and commas.
00:49
Now, try to prepend the *
unpacking operator to the name of your list. Here, the operator tells print()
to unpack the list first.
00:59
In this case, the output is no longer the list itself, but rather the content of the list. Can you see the difference between this execution and the previous one? Instead of a list, print()
now has taken three separate arguments as the input.
01:13
Another thing you’ll notice is that you used the *
unpacking operator to call a function instead of in a function definition. In this case, the print()
function takes all the items of a list as though they were single arguments. You can also use this method to call your own functions, but if your function requires a specific number of arguments, then the iterable you unpack must have the same number of arguments. To test this behavior, consider this script. Here, my_sum()
explicitly states that a
, b
, and c
are required arguments. If you run this script, you’ll get the sum of the three numbers in my_list
.
01:48
The three elements in my_list
match up perfectly with the required arguments in my_sum()
. Now look at this script, where my_list
has four arguments instead of three. In this example, the my_sum()
function still expects just three arguments, but the *
operator gets four items from the list.
02:06 If you try to execute this script, you’ll see that the Python interpreter is unable to run it.
02:13
When you use the *
operator to unpack a list and pass arguments to a function, it’s exactly as though you’re passing every single argument alone.
02:23 This means that you can use multiple unpacking operators to get values from several lists and pass them all to a single function. To test this behavior, consider this example. If you run this example, all three lists are unpacked.
02:37
Each individual item is passed to the my_sum()
function, resulting in the following output.
02:43
There are other convenient uses of the unpacking operator. For example, say you need to split a list into three different parts. The output should show the first value, the last value, and all the values in between. With the unpacking operator, you can do this in just one line of code. In this example, my_list
contains six items. The first variable is assigned to a
, the last to c
, and all other values are packed into a new list b
. If you run the script, the print()
function will show you that your three variables have the values that you would expect.
03:15
Another interesting thing you can do with the *
unpacking operator is to split the items of any iterable object. This could be very useful if you need to merge two lists, for instance.
03:26
The *
unpacking operator is prepended to both my_first_list
and my_second_list
. If you run this script, you’ll see that the result is a merged list.
03:37
You can even merge two different dictionaries by using the **
unpacking operator. Here, the iterables to merge are my_first_dict
and my_second_dict
. Executing this code outputs a merged dictionary.
03:53
Remember that the *
operator works on any iterable object. It can also be used to unpack a string. In Python, strings are iterable objects, so a *
will unpack it and place all individual values in a list called a
. So if we run this script, then we can see our full list.
04:14 The previous example seems great, but when you work with these operators it’s important to keep in mind the seventh rule of the Zen of Python by Tim Peters, which is that “Readability counts.” To see why, consider this example.
04:28
There’s a *
unpacking operator, followed by a variable, a comma, and an assignment. That’s a lot packed into one line! In fact, this code is no different from the previous example.
04:39
It just takes the string "RealPython"
and assigns all the items to the new list a
, thanks to the *
unpacking operator.
04:47
The comma after the a
does the trick. When you use the unpacking operator with variable assignment, Python requires that your resulting variable is either a list or a tuple. With the trailing comma, you have actually defined a tuple with just one named variable a
. While this is a neat trick, many Pythonistas would not consider this code to be very readable. As such, it’s best to use these kinds of constructions sparingly.
zuckerjohn on Jan. 23, 2020
Good observation ‘GJ’, I think you are right.
Here to demonstrate.
>>> a = [‘Python, bytes’]
>>> type(a)
<class ‘list’>
>>> b, = ‘Python, bytes’
>>> type(b)
<class ‘list’>
>>> a == b
True
>>> a == tuple(b)
False
There may be some transferred confusion from a comma idiosyncracy as follows
>>> type((‘singleterm’,))
<class ‘tuple’>
>>> type((‘singleterm’))
<class ‘str’>
Karan Khosla on Feb. 26, 2020
def sum(*args): # Returns a tuple values
Whereas,
my_list = [1, 2, 3, 4, 5]
a, *b, c = my_list
Here, *b
returns a list not a tuple? What am missing here. Please help.
Cristian Palau on May 8, 2020
Thanks for the course!
sndselecta on March 22, 2023
list1 = [1,2,3]
list2 = [3,4,5]
merged_list1 = [*list1, *list2]
> whats difference with
merged_list2 = list1+list2
merged_list1 == merged_list2
> True
Become a Member to join the conversation.
DJ on Jan. 13, 2020
*a, = "RealPython"
a with a trailing comma seems to be a list type, not a tuple