DEV Community

Cover image for The difference between “ *args and **kwargs “ in our Python functions
Mohammed Mokhtar
Mohammed Mokhtar

Posted on

The difference between “ *args and **kwargs “ in our Python functions

Let's start with the normal functions, for which we know what we are sending in our main body to the integrated function. For example, we are going to send 3 variables and print them in our function:

def func_print( x , y , z ): #we have created a function which receives 3 variables 
   print( x )
   print( y )
   print( z )

func_print("mohammed" , 39 , ['id ', 10235 , "name"]) # we sent string , integer, and list 

"""
output will be mohammed
               39
               ['id ', 10235 , "name"]
"""
Enter fullscreen mode Exit fullscreen mode

**Now what will happen if we send another variable to our function?

Image description
So to fix that, we will use “*args“ instead of multiple variables:

def func_print( *args ): #we have created a function which receives 3 variables 
   for y in args :
    print(y)

func_print("mohammed" , 39 , ['id ', 10235 , "name"] , 90 ) # we sent string , integer, and list 

"""
output will be mohammed
               39
               ['id ', 10235 , "name"]
               90
"""
Enter fullscreen mode Exit fullscreen mode

Image description
But what does “*args“ actually make?!
*args allows you to pass a variable number of positional arguments to a function.

These arguments can be integers, strings, lists, dictionaries, or any other data type.

Internally, it collects the arguments passed into a tuple, regardless of the type of the arguments. That is why we have used a for loop to print our data.

But hold on, what should we do if we want to send keyword arguments?!🤔
“**kwargs” will be the solution

“**kwargs” captures keyword arguments as a dictionary, where the keys are the argument names and the values are the corresponding argument values.

This is useful when you want to handle a varying number of named arguments.

let’s say we want to send key-value variables just like dictionary

def func_print( **kwargs ): 
   for x , y in kwargs.items() :
    print(f"The key is {x} while the value is {y}")


func_print(location="Borneo", cause="Illegal logging", area="National Park" )
Enter fullscreen mode Exit fullscreen mode

Image description

As you see, they save those values in a dictionary.

Image description

We have a problem; we can’t send number of dictionaries to function as it will raise an error. So what is the solution?!
It’s simple; we have to place ** before the dictionary name.

Image description
Let’s say we want to use Positional arguments & Keyword arguments together

def func_print(*args , **kwargs ): 
   ## args part
    print("__________________Args Shape________________________")
    print(args)                                                     # Tuple
    print("__________________Args Values________________________")
    for x in arguments:
      print(x)
  ## kwards part
    print("__________________Kwargs Shape________________________")
    print(kwargs)                                                   # Dictionary
    print("__________________Kwargs Values _____________________")
    for x , y in kwargs.items() :
       print(f"The key is {x} while the value is {y}")

dict_new = dict(location="Borneo", cause="Illegal logging", area="National Park" )
func_print(  "Loss of biodiversity", "Climate change" , "Disruption of ecosystems" , name = "Ahmed," , **dict_new  )
Enter fullscreen mode Exit fullscreen mode

Image description
Finally, in that piece:
The difference between *args & **kwargs is:

args: Collects positional arguments into a tuple.
**kwargs: Collects keyword arguments into a dictionary.
**kwargs: is designed for keyword arguments (key-value pairs), not for a single positional argument like a dictionary.
You need to use the *
operator to unpack the dictionary into keyword arguments, which **kwargs can accept.
You can use both together in a function to handle a flexible number of both positional and keyword arguments.
LinkedIN

muhammedmukhtar822@gmail.com

Top comments (0)