DEV Community

Cover image for What Are *args And **kwargs In Python - Guide With Examples
Sachin
Sachin

Posted on • Originally published at geekpython.in

What Are *args And **kwargs In Python - Guide With Examples

When we see the documentation of any function that contains *args and **kwargs, have you ever wondered - What are these strange parameters passed inside that function?

As an example:

function(params, *args, **kwargs)

As a beginner, you might get confused about how to use that function or what to pass as an argument in place of *args and **kwargs when calling that function.

Well not to worry, in this tutorial we gonna discuss *args and **kwargs - What they mean and their uses in the function with examples that help you to understand better.

And we gonna see the glimpse of * and ** (Unpacking operators) used in the examples.

Introduction

The function in Python helps us to write code that is reused, to perform particular tasks in various operations.

Let's define a function that prints the character names.

Example: function that prints character names

def characters(name1, name2, name3):
    print(name1, name2, name3)

characters("Iron Man", "Black Panther", "Captain America")
Enter fullscreen mode Exit fullscreen mode

Output

Iron Man Black Panther Captain America
Enter fullscreen mode Exit fullscreen mode

The function characters above takes 3 positional arguments name1, name2, name3 and simply prints the names.

What if we pass more than the number of arguments that it takes

def characters(name1, name2, name3):
    print(name1, name2, name3)

characters("Iron Man", "Black Panther", "Captain America", "Hulk")
Enter fullscreen mode Exit fullscreen mode

What do you think the output would be, the output will be a TypeError.

TypeError: characters() takes 3 positional arguments but 4 were given
Enter fullscreen mode Exit fullscreen mode

The error was raised because of the extra argument passed inside the function, which only accepts three arguments.

That's unfortunate because we need to pass one more argument inside the function character in order for the code to run without error.

However, this is not the best practice. For example, suppose you are working on a project where you need to add multiple arguments dynamically when calling a specific function.

What should you do in such situations? There is a way to deal with such situations.

Usage of *args

*args is simply shortened for arguments. It is used as an argument when we are not sure how many arguments should we pass in the function.

The * asterisk before the args ensures that the argument has a variable length.

*args is a Non-keyword argument or Positional argument.

By using *args, you are allowed to pass any number of arguments when calling a function.

Example: Using *args in function definition

def friends(*args):
    print(args)

friends("Sachin", "Rishu", "Yashwant", "Abhishek")
Enter fullscreen mode Exit fullscreen mode

Output

('Sachin', 'Rishu', 'Yashwant', 'Abhishek')
Enter fullscreen mode Exit fullscreen mode

We got Tuple because when we use *args the function will get the arguments as tuple.

If we check the type.

def friends(*args):
    print(type(args))
    print(args)

friends("Sachin", "Rishu", "Yashwant", "Abhishek")
Enter fullscreen mode Exit fullscreen mode

Output

<class 'tuple'>
('Sachin', 'Rishu', 'Yashwant', 'Abhishek')
Enter fullscreen mode Exit fullscreen mode

We can also use regular arguments with *args.

Example: Using regular arguments and args in the function definition

def friends(greet, *args):
    for friend in args:
        print(f"{greet} to Python, {friend}")

greet = "Welcome"
friends(greet, "Sachin", "Rishu", "Yashwant", "Abhishek")
Enter fullscreen mode Exit fullscreen mode

Output

Welcome to Python, Sachin
Welcome to Python, Rishu
Welcome to Python, Yashwant
Welcome to Python, Abhishek
Enter fullscreen mode Exit fullscreen mode

Note: You can use any name you want instead of args, including your pet's name, a friend's name, or even your girlfriend's name, as long as you put a * before it.

Example: Using a different name instead of args

def dog(prefix, *german_shepherd):
    for breed in german_shepherd:
        print(f"The {prefix} is {breed}.")

prefix = "breed"
dog(prefix, "Labrador", "GSD", "Chihuahua")
Enter fullscreen mode Exit fullscreen mode

Output

The breed is Labrador.
The breed is GSD.
The breed is Chihuahua.
Enter fullscreen mode Exit fullscreen mode

There is one exception: when passing regular arguments and *args as parameters to a function, never pass *args before regular arguments.

Example: Using *args before regular argument inside the function

def heroes(*characters, country):
    for character in characters:
        print(f"{character} is from {country}.")

country = "USA"
heroes(country, "Iron Man", "Captain America", "Spiderman")
Enter fullscreen mode Exit fullscreen mode

Output

TypeError: heroes() missing 1 required keyword-only argument: 'country'
Enter fullscreen mode Exit fullscreen mode

We got a TypeError because we cannot pass *args before the regular argument.

There will be no error if we change the code and move the parameters passed inside the function.

def heroes(country, *characters):
    for character in characters:
        print(f"{character} is from {country}.")

country = "USA"
heroes(country, "Iron Man", "Captain America", "Spiderman")
Enter fullscreen mode Exit fullscreen mode

Output

Iron Man is from USA.
Captain America is from USA.
Spiderman is from USA.
Enter fullscreen mode Exit fullscreen mode

The above code was executed without any error.

Usage of **kwargs

**kwargs is shortened for Keyword argument.

Now you are familiar with *args and know its implementation, **kwargs works similarly as *args.

But unlike *args, **kwargs takes keyword or named arguments.

In **kwargs, we use ** double asterisk that allows us to pass through keyword arguments.

Example: Using **kwargs in the function definition

def hello(**kwargs):
    print(type(kwargs))
    for key, value in kwargs.items():
        print(f"{key} is {value}.")

hello(One = "Red", two = "Green", three = "Blue")
Enter fullscreen mode Exit fullscreen mode

Output

<class 'dict'>
One is Red.
two is Green.
three is Blue.
Enter fullscreen mode Exit fullscreen mode

The type of **kwargs is Dictionary i.e., the arguments accepted as key-value.

Example: Using regular argument and **kwargs together inside the function definition

def hello(write, **kwargs):
    print(write)
    for key, value in kwargs.items():
        print(f"{key} is {value}.")
write = "RGB stands for:"
hello(write, One = "Red", two = "Green", three = "Blue")
Enter fullscreen mode Exit fullscreen mode

Output

RGB stands for:
One is Red.
two is Green.
three is Blue.
Enter fullscreen mode Exit fullscreen mode

Just like *args, you can choose any name instead of **kwargs

Example: Using a different name instead of kwargs

def hello(write, **color):
    print(write)
    for key, value in color.items():
        print(f"{key} is {value}.")
write = "RGB stand for:"
hello(write, One = "Red", two = "Green", three = "Blue")
Enter fullscreen mode Exit fullscreen mode

Output

RGB stand for:
One is Red.
two is Green.
three is Blue.
Enter fullscreen mode Exit fullscreen mode

Note: We cannot pass **kwargs before *args in the function definition otherwise, we'll get a SyntaxError.

The convention should be - function(params, *args, **kwargs)

Example

We can use all three types of arguments inside the function definition and in this example, we'll see the use of the unpacking operator - * and **.

def friends(greet, *args, **kwargs):
    for names in args:
        print(f"{greet} to the Programming zone {names}")
    print("\nI am Veronica and I would like to announce your roles:")
    for key, value in kwargs.items():
        print(f"{key} is a {value}")

greet = "Welcome"
names = ["Sachin", "Rishu", "Yashwant", "Abhishek"]
roles = {"Sachin":"Chief Instructor", "Rishu":"Engineer",
         "Yashwant":"Lab Technician", "Abhishek":"Marketing Manager"}

friends(greet, *names, **roles)
Enter fullscreen mode Exit fullscreen mode

Output

Welcome to the Programming zone Sachin
Welcome to the Programming zone Rishu
Welcome to the Programming zone Yashwant
Welcome to the Programming zone Abhishek

I am Veronica and I would like to announce your roles:
Sachin is a Chief Instructor
Rishu is a Engineer
Yashwant is a Lab Technician
Abhishek is a Marketing Manager
Enter fullscreen mode Exit fullscreen mode

You'll notice that the variables called names and roles in the above code were used.

However, we put * before the names variable and ** before the roles variable when we passed them inside the function.

These are the Unpacking operators.

Unpacking Operator

These operators come quite in handy as you saw above.

* single asterisk is used to unpack iterable and ** double asterisk is used to unpack dictionary.

The * iterable unpacking operator and ** dictionary unpacking operators to allow unpacking in more positions, an arbitrary number of times, and in additional circumstances. Specifically, in function calls, in comprehensions and generator expressions, and in displays. Source

To know more, click here


Conclusion

So far you will now be able to implement the fundamentals of *args and **kwargs inside the functions.

These might come in handy when you are working on projects where data comes dynamically in a function and you don't know how many arguments to be passed in that function. This makes your project scalable.


πŸ†Other articles you might be interested in if you liked this one

βœ…Context managers and the with statement in Python.

βœ…Display local and web images in the Jupyter Notebook.

βœ…Public, Protected, and Private access modifiers in Python.

βœ…How to change the string representation of the objects using the str and repr method?

βœ…What is enumerate() function in Python?

βœ…Execute dynamically generated code using the exec() in Python.

βœ…Difference between the reverse() and the reversed() function in Python.


That's all for now

Keep Coding✌✌.

Top comments (5)

Collapse
 
mxglt profile image
Maxime Guilbert

Excellent post! It's very simple and well explained!

Collapse
 
sachingeek profile image
Sachin

Glad, you liked it

Collapse
 
shangab profile image
Abubaker Shangab

Awesome thanks

Collapse
 
sachingeek profile image
Sachin

Thanks for the appreciation.

Collapse
 
laureanorp profile image
Laureano Ruiz

Excellent explanation. I didn't know about the unpacking operators, I was just used to see them but didn't fully understand them :)