The Different Usages Of Asterisks In Python

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.

Unpack List

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']


Unpack Dictionary

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}


Unpack Function Arguments

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)


Function Positional Arguments

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")


Keyword-Only Arguments

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")


Function Keyword Arguments

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!

Conclusion

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!

Designed, built and maintained by Kimserey Lam.