loading...

Python: What are *args and **kwargs?

adamlombard profile image Adam Lombard ・2 min read

We may encounter Python function definitions that look something like this:

def a_function(*args, **kwargs):
    ...

The asterisks denote parameters able to receive variable-length arguments. (The args and kwargs names don't matter — they're merely conventions, and stand for 'arguments' and 'keyword arguments' respectively. Any appropriate parameter names may be used.)

Say we need a function enabling users to share their hobbies, but we don't know in advance how many hobbies a given user will have:

def my_hobbies(*hobbies):
    print("My hobbies: " + ", ".join(hobbies))

Our function now accepts one or more arguments:

>>> my_hobbies('reading', 'writing')
My hobbies: reading, writing

>>> my_hobbies('reading', 'writing', 'hiking', 'learning Python')
My hobbies: reading, writing, hiking, learning Python

Conveniently, we can also call our function by passing it a tuple, using similar asterisk syntax:

>>> some_hobbies = ('reading', 'writing', 'hiking', 'learning Python')
>>> my_hobbies(*some_hobbies)
My hobbies: reading, writing, hiking, learning Python

Now say we want a function enabling users to share their favorite things in various categories, but we don't know in advance how many categories a given user will select:

def my_faves(**favorites):
    print("My favorite things...")
    for category, fave in favorites.items():
        print(f"{category}: {fave}")

Our function now accepts one or more keyword arguments:

>>> my_faves(Color='green', Fruit='persimmon')
My favorite things...
Color: green
Fruit: persimmon

>>> my_faves(Season='winter', Language='Python', Website='dev.to')
My favorite things...
Season: fall
Language: Python
Website: dev.to

We can also call our function by passing it a dictionary, using similar double asterisk syntax:

>>> some_faves = {"Animal": "whale", "Summer Hobby": "hiking"}
>>> my_faves(**some_faves)
My favorite things...
Animal: whale
Summer Hobby: hiking

A function may be defined with a mixture of formal parameters, variable-length parameters, and variable-length keyword parameters. When doing so, they must appear in the definition in the following order:

def a_function(arg, *args, **kwargs):
    ...

More information can be found in the Python documentation.

Discussion

pic
Editor guide
Collapse
waylonwalker profile image
Waylon Walker

*args and **kwargs are so powerful. I have cut large sections of hard to maintain code completely out with them. I do find it hard to teach/learn/grasp. I just released a post trying to share them as well.

I think some of this comes from seeing really confusing implementations. I really like how you chose to use *hobbies and **favorites here. I think generalizing with *args and **kwargs only adds to the confusion, and for some reason that is what appears more often than not.

understanding python args and kwargs

Collapse
serg_syd profile image
Sergio

What is the difference if I just used list or dictionary as arguments?

def my_hobbies(hobbies_list):
print("My hobbies: " + ", ".join(hobbies_list))

Collapse
adamlombard profile image
Adam Lombard Author

In our simple example, there isn't much of a difference.

In a real-world example, the *args and *kwargs syntax give us more options in how we accept data into our function.

The decision is largely one between forcing the use of structured data, and not needing to know the structure in advance. In your example, we must always pass in a list or dictionary, even if we are only passing in a single hobby. (This approach is not necessarily bad -- it may, in fact, be the right solution.) If, instead, we allow variable-length arguments -- by using the *args or *kwargs syntax -- then we do not need to structure the data in advance.

A more in-depth discussion related to your question can be found here.

Collapse
hasii2011 profile image
Humberto A Sanchez II

A nice simple concise explanation of args and kwargs

Collapse
adamlombard profile image
Adam Lombard Author

Thanks! 🙂

Collapse
machanic16 profile image
Joel Tovar

Excellent explanation, thanks!

Collapse
adamlombard profile image
Adam Lombard Author

You're welcome! 🙂