Intermediate Python

*args and **kwargs


Python provides a way to handle arbitrary numbers of arguments in a function through special symbols. These symbols are * and **, and are used in front of variable names to denote *args and **kwargs respectively. You can give the *args or **kwargs parameters any names you like, but by convention, they are called args (arguments) and kwargs (keyword arguments).
*args is used to send an arbitrary number of arguments to the function without keywords. Here is an example:
def add(*args):
    res = 0             # Initialize the final result to 0
    for num in args:    # Loop through the list of passed arguments
        res += num      # add each number to the sum
    return res

print(add(3, 5, 7, 9))  # 24
In this program, args is a tuple with the values we pass to the function. So, in the example above, args equals (3, 5, 7, 9). This way we can pass any number of arguments to our function.


**kwargs allows us to pass an arbitrary number of arguments with keywords. In other words, we use *kwargs to pass any number of keyword arguments to our function. Here is an example:
def introduce(**kwargs):
    for key, value in kwargs.items():  # Loop through all the key-value pairs
        print(f'{key}: {value}')       # prints each key-value pair

introduce(Name='Alice', Age=25, Country='USA')  
# 'Name: Alice'
# 'Age: 25'
# 'Country: USA'
In the program above, kwargs is a dictionary with key-value pairs we pass to the function. So, in the example above, kwargs equals {'Name': 'Alice', 'Age': 25, 'Country': 'USA'}.
You can also combine *args and **kwargs in a function call. *args must come before **kwargs.
def combined_example(*args, **kwargs):
    print(args)    # prints the tuple of arguments
    print(kwargs)  # prints the dictionary of keyword arguments

combined_example(1, 2, 3, Name='Alice', Age=25)  
# (1, 2, 3)
# {'Name': 'Alice', 'Age': 25}
In this function, args is a tuple with values (1, 2, 3) and kwargs is a dictionary with values {'Name': 'Alice', 'Age': 25}.
This flexibility of handling any number of arguments and keyword arguments can be really useful when you want your functions to be more dynamic and versatile.

Combining *args and **kwargs with regular function arguments

*args and **kwargs can be used in combination with regular function arguments. In these cases, you have to keep a few rules in mind:
  1. The correct order of the arguments in the function definition should be: standard arguments, *args, then **kwargs.
  1. Standard arguments (also known as positional arguments) must always be specified before *args and **kwargs.
def function_example(a, b, *args, **kwargs):
    print(a)       # print the first standard argument
    print(b)       # print the second standard argument
    print(args)    # print additional non-keyworded arguments
    print(kwargs)  # print keyworded arguments

function_example(1, 2, 3, 4, 5, Name='Alice', Age=25)
# 1
# 2
# (3, 4, 5)
# {'Name': 'Alice', 'Age': 25}
Here 1 and 2 are standard arguments that match to a and b in the function definition. The tuple (3, 4, 5) represents additional arguments that are grouped into args. The remaining keyword arguments are grouped into kwargs as a dictionary.
When using *args and **kwargs with standard arguments, ensure that the standard arguments aren't forgotten when calling the function, as this would raise a TypeError. For example, calling function_example(1, Name='Alice', Age=25) without providing a value for the argument b would result in an error.
To check your solution you need to sign in
Sign in to continue