What Exactly Is The *args and **kwargs Parameters In Python🐍

What Exactly Is The *args and **kwargs Parameters In Python🐍

Python *args and **kwargs: Explained

So you've started coding in Python,and along the way you might have come across these two strange variables: *args and **kwargs. If you’ve ever wondered what these peculiar variables are, then this article is for you. In this we are gonna take a deep dive in understanding what exactly is the args and kwargs in Python.

Passing Multiple Arguments to a Function

The *args and **kwargs parameters comes into play when we want to pass multiple arguments or keyword arguments to a function. There are a few ways you can pass varying number of arguments to a function. The first way which i often see beginners do is to pass a list or a set of all the arguments to their function known as the collection method.

# using the collection method
def my_sum (my_collection):
    result = 0
    for x in my_collection:
        result += x

    return result

list_of_numbers = [1, 2, 3]
print(my_sum(list_of_numbers)) 
# outputs : 5

Hmm this implementation works, but there's a huge limitation , whenever you call this function you’ll also need to create a list of arguments to pass to it. This is an inconvenient and bad practice, especially when you have no ideal what exactly should go into the list.

Okay I'm Lost

This is where the python *args variable can be really useful, because it allows you to pass a varying number of positional arguments to a function or class.

1. Using the Python args Variable in Function Definitions

The *args variable allows you to pass multiple positional arguments to a function.

Now lets rewrite our my_sum function to use the *args parameter

# using the python `*` unpacking operator
def my_sum(*args):
    result = 0
    # Iterating over the Python args tuple
    for x in args:
        result += x
    return result

print(my_sum(1, 2, 3)) #outputs : 5

Now you’re no longer going through the stress of passing a list to my_sum(). Instead, you’re passing three different positional arguments. my_sum() takes all the parameters that are provided in the input and packs them all into a single iterable object named args.

Note that args is just a name. You’re not required to use the name args. You can choose any name that you prefer, such as integers: All that matters here is that you use the list/tuple unpacking operator (*).

2. Using the Python Kwargs Variable in Function Definitions

Okay, now you’ve understood what *args is for, but what about **kwargs? **kwargs works just like *args, the difference is instead of accepting positional arguments it accepts keyword (or named) arguments. Take the following example:

def concatenation (**kwargs):
    result = ""
    # Iterating over the kwargs dictionary
    for arg in kwargs.values():
        result += arg + " "
    return result

print(concatenation(a="ML and AI", b="in Python", c="Is", d="Great", e="!"))
#outputs: ML and AI in Python Is Great !

When the above code is executed, concatenation() will iterate through the Python kwargs dictionary we pass to the function and concatenate all the values it finds:

Bear In mind that in the example above, the iterable object is a standard dict. If you are iterating over a dictionary and want to return its values, like in the example shown, then you must use the .values() method

Like args, kwargs is just a name that can be changed to whatever you want. Again, what is important here is the use of the dictionary unpacking operator (**) .

3. Remembering That Order Of Arguments In A Function Counts

🎉🎉 Now you have learnt what *args and **kwargs are used for In Python, you are ready to start writing functions that take a varying number of input arguments. But what if you want to create a function that takes a changeable number of both positional and named arguments?

In this case, you have to bear in mind that order of arguments counts. Just as non-default/positional arguments have to precede default/named arguments, so *args must come before **kwargs.

To recap, the correct order for your parameters is:

  1. Standard arguments
  2. *args arguments
  3. **kwargs arguments

adhering to the correct order of arguments in the function definition

def my_function(a, b, *args, **kwargs):
    pass

The Standard arguments is listed before the *args variable which is listed before **kwargs.

4. Unpacking With the Asterisk Operators: * & **

You are now able to use *args and **kwargs to define Python functions that take a varying number of input arguments. awesome right! 😃, Let’s go a little deeper to understand more about the unpacking operators.

The single and double asterisk unpacking operators were introduced in Python 2. As of the 3.5 release, they have become even more powerful, thanks to PEP 448. In short, the unpacking operators are operators that unpack the values from iterable objects in Python

The Single Asterisk Operator *

The single asterisk operator * can be used on any iterable that Python provides

>>> my_list = [1, 2, 3]
>>> print(*my_list) #outputs: 1 2 3
>>> 1, 2, 3

Here, the * operator tells print() to unpack the list first.

Here we used the unpacking operator * to call a function, instead of in a function definition. If you are coming from a JavaScript background this operation is commonly known as Destructuring. In this case, print() takes all the items of a list as though they were single arguments

Another really cool thing you can do with the unpacking operator * is to split the items of any iterable object. This could be very useful for merging the iterable objects together:

>>> first_list = [1, 2, 3]
>>> second_list = [4, 5, 6]
>>> merged_list = [*first_list, *second_list]
>>> print(merged_list) #outputs: [1, 2, 3, 4, 5, 6]
>>> [1, 2, 3, 4, 5, 6]

The unpacking operator * is prepended to both first_list and second_list unpacking their values and storing it into the merged_list variable .

The Double Asterisk Operator **

The Double asterisk operator ** can only be used on dictionaries in python.

>>> person_1 = {"name1": "Victor", "age1": 16}
>>> person_2 = {"name2": "Linda", "age2": 23}
>>> persons_dict = {**person_1, **person_2}
>>> print(persons_dict)
>>> {'name1': 'Victor', 'age1': 16, 'name2': 'Linda', 'age2': 23}

Tip to Note:

When you use the Asterisk operator to unpack an iterable to a function, it’s exactly as though you’re passing every single argument alone

Conclusion

Cheers🥂🎉 in this article i introduced you to the power and incredible usefulness of the *args and **kwargs parameters in python. You are now able to use *args and **kwargs to accept a changeable number of arguments in your functions.

You’ve covered:

  • What *args and **kwargs actually are
  • How to use *args and **kwargs in function definitions
  • How to use a single asterisk (*) to unpack iterables
  • How to use double asterisks (**) to unpack only dictionaries

If you still have questions, don’t hesitate to reach out to me in the comments section below!. Now, go and write some awesome pythonic code with this new found knowledge!

if you enjoyed reading this as much as I enjoyed writing it, then Like and Share this with your friends and feel free to follow me on Twitter so you won't miss my latest articles again.

Wanna Support then Buy Me A Coffee 😊❤