What do *args and **kwargs mean?
def foo(x, y, *args):
def bar(x, y, **kwargs):
What do *args and **kwargs mean?
def foo(x, y, *args):
def bar(x, y, **kwargs):
The *args and **kwargs is a common idiom to allow arbitrary number of arguments to functions as described in the section more on defining functions in the Python documentation.
The *args will give you all function parameters as a tuple:
def foo(*args):
for a in args:
print(a)
foo(1)
# 1
foo(1,2,3)
# 1
# 2
# 3
The **kwargs will give you all
keyword arguments except for those corresponding to a formal parameter as a dictionary.
def bar(**kwargs):
for a in kwargs:
print(a, kwargs[a])
bar(name='one', age=27)
# name one
# age 27
Both idioms can be mixed with normal arguments to allow a set of fixed and some variable arguments:
def foo(kind, *args, **kwargs):
pass
It is also possible to use this the other way around:
def foo(a, b, c):
print(a, b, c)
obj = {'b':10, 'c':'lee'}
foo(100,**obj)
# 100 10 lee
Another usage of the *l idiom is to unpack argument lists when calling a function.
def foo(bar, lee):
print(bar, lee)
l = [1,2]
foo(*l)
# 1 2
In Python 3 it is possible to use *l on the left side of an assignment (Extended Iterable Unpacking), though it gives a list instead of a tuple in this context:
first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]
Also Python 3 adds new semantic (refer PEP 3102):
def func(arg1, arg2, arg3, *, kwarg1, kwarg2):
pass
For example the following works in python 3 but not python 2:
>>> x = [1, 2]
>>> [*x]
[1, 2]
>>> [*x, 3, 4]
[1, 2, 3, 4]
>>> x = {1:1, 2:2}
>>> x
{1: 1, 2: 2}
>>> {**x, 3:3, 4:4}
{1: 1, 2: 2, 3: 3, 4: 4}
Such function accepts only 3 positional arguments, and everything after * can only be passed as keyword arguments.
dict, semantically used for keyword argument passing, are arbitrarily ordered. However, in Python 3.6, keyword arguments are guaranteed to remember insertion order.**kwargs now corresponds to the order in which keyword arguments were passed to the function." - What’s New In Python 3.6It's also worth noting that you can use * and ** when calling functions as well. This is a shortcut that allows you to pass multiple arguments to a function directly using either a list/tuple or a dictionary. For example, if you have the following function:
def foo(x,y,z):
print("x=" + str(x))
print("y=" + str(y))
print("z=" + str(z))
You can do things like:
>>> mylist = [1,2,3]
>>> foo(*mylist)
x=1
y=2
z=3
>>> mydict = {'x':1,'y':2,'z':3}
>>> foo(**mydict)
x=1
y=2
z=3
>>> mytuple = (1, 2, 3)
>>> foo(*mytuple)
x=1
y=2
z=3
Note: The keys in mydict have to be named exactly like the parameters of function foo. Otherwise it will throw a TypeError:
>>> mydict = {'x':1,'y':2,'z':3,'badnews':9}
>>> foo(**mydict)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() got an unexpected keyword argument 'badnews'
The single * means that there can be any number of extra positional arguments. foo() can be invoked like foo(1,2,3,4,5). In the body of foo() param2 is a sequence containing 2-5.
The double ** means there can be any number of extra named parameters. bar() can be invoked like bar(1, a=2, b=3). In the body of bar() param2 is a dictionary containing {'a':2, 'b':3 }
With the following code:
def foo(param1, *param2):
print(param1)
print(param2)
def bar(param1, **param2):
print(param1)
print(param2)
foo(1,2,3,4,5)
bar(1,a=2,b=3)
the output is
1
(2, 3, 4, 5)
1
{'a': 2, 'b': 3}
* is to give you the ability to define a function that can take an arbitrary number of arguments provided as a list (e.g. f(*myList) ).** is to give you the ability to feed a function's arguments by providing a dictionary (e.g. f(**{'x' : 1, 'y' : 2}) ).Let us show this by defining a function that takes two normal variables x, y, and can accept more arguments as myArgs, and can accept even more arguments as myKW. Later, we will show how to feed y using myArgDict.
def f(x, y, *myArgs, **myKW):
print("# x = {}".format(x))
print("# y = {}".format(y))
print("# myArgs = {}".format(myArgs))
print("# myKW = {}".format(myKW))
print("# ----------------------------------------------------------------------")
# Define a list for demonstration purposes
myList = ["Left", "Right", "Up", "Down"]
# Define a dictionary for demonstration purposes
myDict = {"Wubba": "lubba", "Dub": "dub"}
# Define a dictionary to feed y
myArgDict = {'y': "Why?", 'y0': "Why not?", "q": "Here is a cue!"}
# The 1st elem of myList feeds y
f("myEx", *myList, **myDict)
# x = myEx
# y = Left
# myArgs = ('Right', 'Up', 'Down')
# myKW = {'Wubba': 'lubba', 'Dub': 'dub'}
# ----------------------------------------------------------------------
# y is matched and fed first
# The rest of myArgDict becomes additional arguments feeding myKW
f("myEx", **myArgDict)
# x = myEx
# y = Why?
# myArgs = ()
# myKW = {'y0': 'Why not?', 'q': 'Here is a cue!'}
# ----------------------------------------------------------------------
# The rest of myArgDict becomes additional arguments feeding myArgs
f("myEx", *myArgDict)
# x = myEx
# y = y
# myArgs = ('y0', 'q')
# myKW = {}
# ----------------------------------------------------------------------
# Feed extra arguments manually and append even more from my list
f("myEx", 4, 42, 420, *myList, *myDict, **myDict)
# x = myEx
# y = 4
# myArgs = (42, 420, 'Left', 'Right', 'Up', 'Down', 'Wubba', 'Dub')
# myKW = {'Wubba': 'lubba', 'Dub': 'dub'}
# ----------------------------------------------------------------------
# Without the stars, the entire provided list and dict become x, and y:
f(myList, myDict)
# x = ['Left', 'Right', 'Up', 'Down']
# y = {'Wubba': 'lubba', 'Dub': 'dub'}
# myArgs = ()
# myKW = {}
# ----------------------------------------------------------------------
** is exclusively reserved for dictionaries.** must come after *, always.TL;DR
Below are 6 different use cases for * and ** in python programming:
*args: def foo(*args): pass, here foo accepts any number of positional arguments, i. e., the following calls are valid foo(1), foo(1, 'bar')**kwargs: def foo(**kwargs): pass, here 'foo' accepts any number of keyword arguments, i. e., the following calls are valid foo(name='Tom'), foo(name='Tom', age=33)*args, **kwargs: def foo(*args, **kwargs): pass, here foo accepts any number of positional and keyword arguments, i. e., the following calls are valid foo(1,name='Tom'), foo(1, 'bar', name='Tom', age=33)*: def foo(pos1, pos2, *, kwarg1): pass, here * means that foo only accept keyword arguments after pos2, hence foo(1, 2, 3) raises TypeError but foo(1, 2, kwarg1=3) is ok.*_ (Note: this is a convention only): def foo(bar, baz, *_): pass means (by convention) foo only uses bar and baz arguments in its working and will ignore others.\**_ (Note: this is a convention only): def foo(bar, baz, **_): pass means (by convention) foo only uses bar and baz arguments in its working and will ignore others.BONUS: From python 3.8 onward, one can use / in function definition to enforce positional only parameters. In the following example, parameters a and b are positional-only, while c or d can be positional or keyword, and e or f are required to be keywords:
def f(a, b, /, c, d, *, e, f):
pass
From the Python documentation:
If there are more positional arguments than there are formal parameter slots, a TypeError exception is raised, unless a formal parameter using the syntax "*identifier" is present; in this case, that formal parameter receives a tuple containing the excess positional arguments (or an empty tuple if there were no excess positional arguments).
If any keyword argument does not correspond to a formal parameter name, a TypeError exception is raised, unless a formal parameter using the syntax "**identifier" is present; in this case, that formal parameter receives a dictionary containing the excess keyword arguments (using the keywords as keys and the argument values as corresponding values), or a (new) empty dictionary if there were no excess keyword arguments.
* means receive variable arguments as tuple
** means receive variable arguments as dictionary
Used like the following:
1) single *
def foo(*args):
for arg in args:
print(arg)
foo("two", 3)
Output:
two
3
2) Now **
def bar(**kwargs):
for key in kwargs:
print(key, kwargs[key])
bar(dic1="two", dic2=3)
Output:
dic1 two
dic2 3
It packs arguments passed to the function into list and dict respectively inside the function body. When you define a function signature like this:
def func(*args, **kwds):
# do stuff
it can be called with any number of arguments and keyword arguments. The non-keyword arguments get packed into a list called args inside the function body and the keyword arguments get packed into a dict called kwds inside the function body.
func("this", "is a list of", "non-keyowrd", "arguments", keyword="ligma", options=[1,2,3])
now inside the function body, when the function is called, there are two local variables, args which is a list having value ["this", "is a list of", "non-keyword", "arguments"] and kwds which is a dict having value {"keyword" : "ligma", "options" : [1,2,3]}
This also works in reverse, i.e. from the caller side. for example if you have a function defined as:
def f(a, b, c, d=1, e=10):
# do stuff
you can call it with by unpacking iterables or mappings you have in the calling scope:
iterable = [1, 20, 500]
mapping = {"d" : 100, "e": 3}
f(*iterable, **mapping)
# That call is equivalent to
f(1, 20, 500, d=100, e=3)
Building on nickd's answer...
def foo(param1, *param2):
print(param1)
print(param2)
def bar(param1, **param2):
print(param1)
print(param2)
def three_params(param1, *param2, **param3):
print(param1)
print(param2)
print(param3)
foo(1, 2, 3, 4, 5)
print("\n")
bar(1, a=2, b=3)
print("\n")
three_params(1, 2, 3, 4, s=5)
Output:
1
(2, 3, 4, 5)
1
{'a': 2, 'b': 3}
1
(2, 3, 4)
{'s': 5}
Basically, any number of positional arguments can use *args and any named arguments (or kwargs aka keyword arguments) can use **kwargs.
*args and **kwargs: allow you to pass a variable number of arguments to a function.
*args: is used to send a non-keyworded variable length argument list to the function:
def args(normal_arg, *argv):
print("normal argument:", normal_arg)
for arg in argv:
print("Argument in list of arguments from *argv:", arg)
args('animals', 'fish', 'duck', 'bird')
Will produce:
normal argument: animals
Argument in list of arguments from *argv: fish
Argument in list of arguments from *argv: duck
Argument in list of arguments from *argv: bird
**kwargs*
**kwargs allows you to pass keyworded variable length of arguments to a function. You should use **kwargs if you want to handle named arguments in a function.
def who(**kwargs):
if kwargs is not None:
for key, value in kwargs.items():
print("Your %s is %s." % (key, value))
who(name="Nikola", last_name="Tesla", birthday="7.10.1856", birthplace="Croatia")
Will produce:
Your name is Nikola.
Your last_name is Tesla.
Your birthday is 7.10.1856.
Your birthplace is Croatia.
Given a function that has 3 items as argument
sum = lambda x, y, z: x + y + z
sum(1,2,3) # sum 3 items
sum([1,2,3]) # error, needs 3 items, not 1 list
x = [1,2,3][0]
y = [1,2,3][1]
z = [1,2,3][2]
sum(x,y,z) # ok
sum(*[1,2,3]) # ok, 1 list becomes 3 items
Imagine this toy with a bag of a triangle, a circle and a rectangle item. That bag does not directly fit. You need to unpack the bag to take those 3 items and now they fit. The Python * operator does this unpack process.
A good example of using both in a function is:
>>> def foo(*arg,**kwargs):
... print arg
... print kwargs
>>>
>>> a = (1, 2, 3)
>>> b = {'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(*a,**b)
(1, 2, 3)
{'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(a,**b)
((1, 2, 3),)
{'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(a,b)
((1, 2, 3), {'aa': 11, 'bb': 22})
{}
>>>
>>>
>>> foo(a,*b)
((1, 2, 3), 'aa', 'bb')
{}
**In addition to the answers in this thread, here is another detail that was not mentioned elsewhere. This expands on the answer by Brad Solomon
Unpacking with ** is also useful when using python str.format.
This is somewhat similar to what you can do with python f-strings f-string but with the added overhead of declaring a dict to hold the variables (f-string does not require a dict).
## init vars
ddvars = dict()
ddcalc = dict()
pass
ddvars['fname'] = 'Huomer'
ddvars['lname'] = 'Huimpson'
ddvars['motto'] = 'I love donuts!'
ddvars['age'] = 33
pass
ddcalc['ydiff'] = 5
ddcalc['ycalc'] = ddvars['age'] + ddcalc['ydiff']
pass
vdemo = []
## ********************
## single unpack supported in py 2.7
vdemo.append('''
Hello {fname} {lname}!
Today you are {age} years old!
We love your motto "{motto}" and we agree with you!
'''.format(**ddvars))
pass
## ********************
## multiple unpack supported in py 3.x
vdemo.append('''
Hello {fname} {lname}!
In {ydiff} years you will be {ycalc} years old!
'''.format(**ddvars,**ddcalc))
pass
## ********************
print(vdemo[-1])
*args ( or *any ) means every parameters
def any_param(*param):
pass
any_param(1)
any_param(1,1)
any_param(1,1,1)
any_param(1,...)
NOTICE : you can don't pass parameters to *args
def any_param(*param):
pass
any_param() # will work correct
The *args is in type tuple
def any_param(*param):
return type(param)
any_param(1) #tuple
any_param() # tuple
for access to elements don't use of *
def any(*param):
param[0] # correct
def any(*param):
*param[0] # incorrect
The **kwd
**kwd or **any This is a dict type
def func(**any):
return type(any) # dict
def func(**any):
return any
func(width="10",height="20") # {width="10",height="20")
def foo(param1, *param2): is a method can accept arbitrary number of values for *param2,def bar(param1, **param2): is a method can accept arbitrary number of values with keys for *param2param1 is a simple parameter.For example, the syntax for implementing varargs in Java as follows:
accessModifier methodName(datatype… arg) {
// method body
}
*args and **kwargs are just some way to input unlimited characters to functions, like:
def print_all(*args, **kwargs):
print(args) # print any number of arguments like: "print_all("foo", "bar")"
print(kwargs.get("to_print")) # print the value of the keyworded argument "to_print"
# example:
print_all("Hello", "World", to_print="!")
# will print:
"""
('Hello', 'World')
!
"""