May 21st, 2021 - written by Kimserey with .
In Python, we often see asterisks being used for other operation than the infix operations like multiplication. In today’s post we will look at the other scenario were we encounter the asterisk and understand the meaning of it in those different contexts.
It can be used to unpack a list into another list:
1
2
x = [1, 2, 3]
[0, *x]
will result in:
1
[0, 1, 2, 3]
or to unpack attributes from a dictionary:
1
2
y = {'firstname': 'Tom', 'lastname': 'Clancy'}
[*y]
will result in:
1
['firstname', 'lastname']
A double asterisk can be used to unpack a dictionary into another dictionary:
1
2
x = {"a": 1, "b": 2}
{**x, "c": 3}
will result in:
1
{'a': 1, 'b': 2, 'c': 3}
And it can be used to unpack arguments into a function, for example here we have a function accepting two arguments:
1
2
3
4
5
def say_hello(firstname, lastname):
print(firstname + " " + lastname)
x = ["Tom", "Clancy"]
say_hello(*x)
will result in:
1
Tom Clancy
And a double astrisk can be used to unpack a dictionary as keyword arguments:
1
2
y = {"firstname": "Tom", "lastname": "Clancy"}
say_hello(**y)
Asterisks are also seen in function definitions, the most common being positional arguments and keyword arguments. Specifying a positional argument with an asterisk works as a catch-all for all positional arguments.
1
2
3
def say_hello(*args):
print(args)
say_hello(1, 2, 3)
args
will capture all arguments as a tuple:
1
(1, 2, 3)
Because args
captures all positional arguments, any argument coming after *args
would be expected to be passed as a keyword-only argument.
1
2
3
def say_hello(*args, name):
print(args)
say_hello(1, 2, 3, "kim")
Doing that will result in an error TypeError: say_hello() missing 1 required keyword-only argument: 'name'
as name
is expected to be passed as a keyword argument.
1
say_hello(1, 2, 3, name="kim")
There are times where we want to have keyword-only arguments but don’t want to allow infinite number of positional arguments, in that case we can use the asterisk to denote the limit between arguments and keyword-only arguments.
For example if we have the following function:
1
2
def say_hello(firstname, lastname, middlename):
print(firstname + " " + lastname + " " + middlename)
We are able to call it via positonal argument, or keyword argument:
1
2
say_hello("Thomas", "Clancy", "Leo")
say_hello("Thomas", middlename="Leo", lastname="Clancy")
If we want to enforce that middlename
should be passed as a keyword argument, we can do the following:
1
2
def say_hello(firstname, lastname, *, middlename):
print(firstname + " " + lastname + " " + middlename)
where the asterisk delimits the keyword-only arguments. If we call it:
1
say_hello("Thomas", "Clancy", "Leo")
we will receive the error TypeError: say_hello() takes 2 positional arguments but 3 were given
. Instead we will have to specify middlename
as a keyword argument:
1
say_hello("Thomas", "Clancy", middlename="Leo")
Lastly a common place to see a double asterisk is on the function definition where we capture all keyword arguments as dictionary:
1
2
3
def say_hello(**kwargs):
print(kwargs)
say_hello(key=1, name="hello")
will result in the following:
1
{'key': 1, 'name': 'hello'}
And that concludes today’s post!
In today’s post we saw all the different flavours in which we can find asterisks being used in Python. From unpacking to function definitions, the asterisk usage is quite diverse and gives a lot of power to express our code. I hope you liked this post and I see you on the next one!