This article explains the concepts of *args and **kwargs and how and when we use them in python program. Seasoned python developers embrace the flexibility it provides when creating functions. If you are beginner in python, you might not have heard it before. After completion of this tutorial, you will have confidence to use them in your live project.
- Introduction : *args
- How to get each argument?
- How to pass lists / tuples in function?
- How to include both fixed and dynamic no. of arguments?
- How to use *args in lambda function?
- How to use *args in list comprehension?
- What is **kwargs?
- How to use both args and kwargs
- Examples : Uses of kwargs
- How to use arguments in Pandas Dataframe
- Bad practices in using args
Introduction : *args
args
is a short form of arguments. With the use of *args
python takes any number of arguments in user-defined function and converts user inputs to a tuple named args
. In other words, *args
means zero or more arguments which are stored in a tuple named args.
When you define function without *args
, it has a fixed number of inputs which means it cannot accept more (or less) arguments than you defined in the function.
In the example code below, we are creating a very basic function which adds two numbers. At the same time, we created a function which can sum more than 2 numbers. Even the function can take less than 2 arguments (zero argument will also work!)
def add(x,y): print(x + y) add(5,5) #Works and returns 10 add(5,5,6) #TypeError: add() takes 2 positional arguments but 3 were given
def add(*args): print(sum(args)) add(5,5,6) # Output : 16
How to get each argument?
You can extract arguments based on index like we get a value from tuple based on index position args[0]
refers to first argument as indexing in python starts from zero.
def add(*args): print(args[0]) print(args[1]) print(args[2]) add(5,5,6) # Output : # 5 # 5 # 6
args
. You can use any naming convention other than args. Refer the code below wherein I used x
instead of args-
def add(*x): return sum(x) add(5,5,6)
You can access arguments in loop by running it over args
tuple.
In this example, we are creating a flag showing categorization of High/Medium/Low based on user inputs. If a value divided by 100 is greater than 7 should be indicated as "High". If it is greater than 5 and less than or equal to 7, it should be shown as "Medium". Otherwise it should be categorized as "Low".
def myfun(*args): for arg in args: if arg/100 > 7: print('High') elif arg/100 >5: print('Medium') elif arg/100 >0: print('Low') myfun(100, 600, 900) # Output : # Low # Medium # High
If you want to store the result in a list, you can do this by creating an empty list initially and then start appending in an iterative matter in loop. The following code produces a list named l.
l = [] def myfun(*args): for arg in args: if arg/100 > 7: flag = 'High' elif arg/100 >5: flag = 'Medium' elif arg/100 >0: flag = 'Low' l.append(flag) return l myfun(800,600,100)
How to pass lists / tuples in function?
By using *
operator, you can unpack a list or tuple. In simple words, it refers to removing brackets (square brackets of list or round brackets of tuple). Think of *[1, 2, 3]
as 1, 2, 3
k = [100, 600, 900] myfun(*k) # Output : # Low # Medium # High
How to include both fixed and dynamic no. of arguments?
Python lets you to include both fixed argument and dynamic number of arguments using *args. It is important to note that it is required to include fixed argument. However you can ignore passing dynamic arguments and it won't return error.
Here we are creating a simple function which adds all the salary components. It comprises of base, variable and other allowances. It is mandatory to include Base salary. Other components you can ignore or include as per need.
def salary(base, *args): return base + sum(args) salary(1000, 3000, 4000) # 8000 salary(1000) # 1000 salary() # Don't work, need to include base argument
By using not
operator, you can find out that the arguments were not passed. len(args)
is used to calculate the number of passed arguments. str( )
is used to convert the result into string format so that it can be concatenated with the text.
def test(*args): if not args: print("Note : You have not passed any argument") else: print("You have passed " + str(len(args)) + " arguments") test(1,5,8) # You have passed 3 arguments test() # Note : You have not passed any argument
How to use *args in lambda function?
The beauty of lambda function is that you can write your user defined function in a single line of code.
add = lambda *args: sum(args) add(1,2,3,4) #To pass a list to function mylist = [1, 2, 3, 4] add(*mylist)Let's take another example : Suppose you want to multiply all the values specified in arguments.
reduce( )
function allows us to apply function (multiplication) on first two values and then iterate again on the result with the third value and keeps going on till the last argument.
from functools import reduce def my_func(*args): return reduce((lambda x, y: x * y), args) my_func(1, 2, 3, 4)
How to use *args in list comprehension?
List comprehension makes coding more readable and is generally faster than For loop and lambda function.In this example, we are selecting all the even numbers which are divisible by 2.
def even(*args): print([n for n in args if n%2 == 0]) even(1,2,3,4) # Output : [2, 4]
What is **kwargs?
**kwargs
stands for keyword arguments. It is very similar to *args
in terms of its objective but there are some differences explained below -
**kwargs
creates dictionary whereas*args
creates tuple.- By using
**kwargs
you can name your arguments which is not possible in*args
.
def test2(**kwargs): print(kwargs) print(kwargs.keys()) print(kwargs.values()) test2(a=1, b=3) # Output : # {'a': 1, 'b': 3} # dict_keys(['a', 'b']) # dict_values([1, 3])
Strings of each keyword are the keys of the dictionary and values assigned after =
symbol are the values of the dictionary. It is also called named arguments.
How to use both args and kwargs
def myfun(*args, **kwargs): return sum(args) + sum(kwargs.values()) myfun(1,2, a=1, b=3) # Output : 7 myfun() # Output : 0
Examples : Uses of kwargs
Suppose you need to build a conditional statement which says sum of all the arguments if a fixed named argument called flag is set 'Yes'. Otherwise ignore the calculation and don't sum values and also throws a message which hints users why calculation has been ignored.def calc(flag='Yes', **i): if flag == 'Yes' : return sum(i.values()) else : print("Flag is set No") calc(x=17, y=20) # Output : 37 calc(flag='No', x=17, y=20) # Output : Flag is set NoIf you observe default value of named argument called flag is
Yes
so we don't need to specify it when we used this code calc(x=17, y=20)
.
kwargs
can be used preceded by **
. In the above example, we used i
instead of kwargs.
Suppose you are asked to create a dynamic user-defined function which calculates total salary depending upon user inputs of performance rating and salary increment (hike).
In the following program, we check the keyword arguments by using in
operator. For example, 'rating' in kwargs
def salary(base=0, **kwargs): if 'rating' in kwargs and kwargs['rating'] == 'high': if 'hike' in kwargs: hike = kwargs['hike'] else: hike = 0.1 return round(base*(1+hike), 2) else: if 'hike' in kwargs: hike = kwargs['hike'] else: hike = 0.05 return round(base*(1+hike), 2)
#If rating is not specified, it will be assumed "average" performer with 5% hike salary(base=10000) #Default hike for average performers 5% salary(base=10000, rating='average') #Default hike for high performers 10% salary(base=10000, rating='high') #Custom hike for average performers 7% salary(base=10000, rating='average', hike =0.07) #Custom hike for high performers 12% salary(base=10000, rating='high', hike =0.12)
How to use arguments in Pandas Dataframe
In this example, we would show you multiple ways to include keyword arguments in dataframe. The most straightforward way to include arguments is to pass them in apply( )
function as named in user-defined function. Another way is to use args=
parameter.
import pandas as pd df = pd.DataFrame({'x1':[11,30,17]}) def myfun(row, l_limit=0, u_limit=0): if l_limit <= row['x1'] <= u_limit: return 1 elif row['x1'] > u_limit: return 2 df.apply(myfun, axis=1, l_limit=10, u_limit=20) df.apply(myfun, axis=1, args=(10,20))
Bad practices in using args
It is always good to practice what we have learnt but we sometimes use it in incorrect way just for the sake of learning new concepts. Then we got a habit of using it in real-world data situations. See the example below wherein instead of using lambda and reduce functions we are considering arguments based on index. It works only when the number of arguments are exactly the same defined in function. For example, args[0]+args[1]+args[2]
works only when 3 arguments are passed.
def add(*args): return reduce(lambda x,y:x+y, args) add(3,4,5)
def add2(*args): return args[0]+args[1]+args[2] add2(3,4,5) #Works add2(3,4) #Error
Hi, Easy to understand since u provide detailed step by step explanation. Thank you!
ReplyDeleteWell explained, on point, well covered..! Thankyou Sir..!
ReplyDelete