Python provides some handy ways through which we could make a function take a variable number of arguments. *args
and **kwargs
do just that.
*args
-> Represents a List / Tuple of positional arguments to be passed to any function
**kwargs
-> Represents a Dictionary of keyword arguments to be passed to any function
Purpose of *args
*args
is commonly used when you’re not sure about the number of arguments that you want to pass as function parameters, when you define the function. So essentially, this type of syntax allows us to pass an arbitrary number of arguments to the function, the exact number being determined at runtime.
There are two cases where the *
(star) operator differs in meaning.
Case 1 : In a function definition
Here, the *
operator is used to pack the arguments into a tuple/list (which contains all the positional) arguments passed to the function. Hence, we use *args
in the definition to signity that all the positional arguments passed to the function are packed into a list/tuple called args
(Any other name can be given, but it is common practice to write *args
to signify that argument packing is used)
def find_average(*args):
total = 0
print('Packed Argument Tuple ->', args)
for i in args:
total += i
return total / len(args)
print('Average ->', find_average(1, 2, 3, 4, 5))
Output
Packed Argument Tuple -> (1, 2, 3, 4, 5)
Average -> 3.0
Case 2: In a function call
Here, the *
operator is used to unpack the corresponding list/tuple passed to it, or even a generator.
a = [1, 2, 3]
print(*a)
Output
1 2 3
This could be useful if you want an iterable to be expanded only the corresponding function is called.
Combining Case1 and Case2 to use *args
Here is an example using both Case1 and Case2 to compute the maximum of a list being unpacked and passed into a function, that takes a variable number of arguments.
def compute_maximum(*args):
maximum = 0
for i in args:
if i > maximum:
maximum = i
return maximum
a = [4, 5, 10, 14, 3]
print('Maximum ->', compute_maximum(*a))
Output
Maximum -> 14
Purpose of **kwargs
Here, the **
operator is used in a way similar to the previous situation, but this is applied exclusively to pack keyword arguments passed to a function into a Dictionary. The **kwargs
idiom only applies to a function definition, and unlike *args
, does not have any special meaning in a function call.
Here is an example to illustrate the purpose of **kwargs
def find_average(**kwargs):
total = 0
print('Keyword Argument Dictionary ->', kwargs)
for key, value in kwargs.items():
total += value
return total / len(kwargs.items())
print('Average ->', find_average(first=1, second=2, third=3, fourth=4, fifth=5))
Output
Keyword Argument Dictionary -> {'first': 1, 'second': 2, 'third': 3, 'fourth': 4, 'fifth': 5}
Average -> 3.0
The *
operator can be used here to unpack the **kwargs
and get all the keys
/values
passed to the keyword Dictionary
>>> print(*kwargs)
first second third fourth fifth
>>> print(*kwargs.values())
1 2 3 4 5
Conclusion
This article helped us gain a deeper understanding of how *args
and **kwargs
can be used in function definitions to get a variable number of positional / keyword arguments and manipulate them, and how programmers use it in common practice for writing easy to use functions.
References
StackOverflow : https://stackoverflow.com/questions/3394835/use-of-args-and-kwargs