SaltyCrane Blog — Notes on Python and web development on Ubuntu Linux

How to use *args and **kwargs in Python

Or, How to use variable length argument lists in Python.

The special syntax, *args and **kwargs in function definitions is used to pass a variable number of arguments to a function. The single asterisk form (*args) is used to pass a non-keyworded, variable-length argument list, and the double asterisk form is used to pass a keyworded, variable-length argument list. Here is an example of how to use the non-keyworded form. This example passes one formal (positional) argument, and two more variable length arguments.

def test_var_args(farg, *args):
    print "formal arg:", farg
    for arg in args:
        print "another arg:", arg

test_var_args(1, "two", 3)

Results:

formal arg: 1
another arg: two
another arg: 3

Here is an example of how to use the keyworded form. Again, one formal argument and two keyworded variable arguments are passed.

def test_var_kwargs(farg, **kwargs):
    print "formal arg:", farg
    for key in kwargs:
        print "another keyword arg: %s: %s" % (key, kwargs[key])

test_var_kwargs(farg=1, myarg2="two", myarg3=3)

Results:

formal arg: 1
another keyword arg: myarg2: two
another keyword arg: myarg3: 3

Using *args and **kwargs when calling a function

This special syntax can be used, not only in function definitions, but also when calling a function.

def test_var_args_call(arg1, arg2, arg3):
    print "arg1:", arg1
    print "arg2:", arg2
    print "arg3:", arg3

args = ("two", 3)
test_var_args_call(1, *args)

Results:

arg1: 1
arg2: two
arg3: 3

Here is an example using the keyworded form when calling a function:

def test_var_args_call(arg1, arg2, arg3):
    print "arg1:", arg1
    print "arg2:", arg2
    print "arg3:", arg3

kwargs = {"arg3": 3, "arg2": "two"}
test_var_args_call(1, **kwargs)

Results:

arg1: 1
arg2: two
arg3: 3

See also (updated 2009-04-12)


Reference: Core Python Programming, Second Edition, Section 11.6

Comments


#1 Skawaii commented on :

Thanks for the succinct explanation of args and *kwargs. You made it nice and easy to understand.


#2 Julien commented on :

thanks for this explanation. It's pretty cool to have such informations easy to understand.


#3 Dmitry commented on :

Thanks for your explanation.


#4 mike commented on :

Thanks just learnt python from Think Python free book, but there was no mention of this. I was seeing it frequently in other peoples code and it was confusing me. Not now. Thanks again!


#5 Eliot commented on :

Mike, I had not heard of Think Python. It looks like a great free Python resource.


#6 Katja commented on :

Awesome! This is THE explanation I was looking for :).


#7 Volkan commented on :

I have newly discovered your blog and it is awsome. Also this is a very good tip. Thanks you!


#8 Richie commented on :

I too want to thank you for your explanation. Just started Python/Django and blogs like this really speed up the task.


#9 Protector one commented on :

Excellent explanation, no wonder it's the first google-hit for 'kwargs'. You might mention that the terms 'args' and 'kwargs' are arbitrary, though. I found out later that you can use any non-keyword identifier, as long as you use the asterisks.


#10 Eliot commented on :

Protector one, you make a good point, the terms "args" and "kwargs" are arbitrary. thank you. i'll try to add a note in the post when i get a chance.


#11 John McCollum commented on :

Excellent, clear explanation. Thanks for the post.


#12 Emma commented on :

Thanks a lot! I have a question:

Here is a function: def myfunction(self, a=None, b=None): pass

Is it possible to make sure that the user will call the function like this:

self.myfunction(a=2, b=3)

self.myfunction(a=2)

self.myfunction(b=3),

and that he won't be able to call the function without specifying which number is which parameter. I don't want this: self.myfunction(2, 3)

self.myfunction(2)

Emma


#13 Eliot commented on :

Emma, That's a good question-- I don't know the answer. If you find the answer, let me know.


#14 Michael Arp Sørensen commented on :

Pretty usefull stuff. I found it usefull for my hobby project.

Python is so cool. :-)


#15 rubixC commented on :

For Emma

if you define your function like this:

def myfunction(self,**kwargs):pass

then u can call it like this:

self.myfunction()
self.myfunction(a=1)
self.myfunction(a=1,b=2)
self.myfunction(a=1,b=2,c=3)
....

if called like self.myfunction(1,2) it will throw an exception. the problem is that with **kwargs u may specify as many parameters as u want (0 to n). U can check how many parameters the user entered (kwargs length) and then print an error message or whatever.


#16 Ubay Oramas commented on :

Thanks!


#17 Nicolas commented on :

I second all that! Thanks for the explanation!


#18 Emma commented on :

Thanks rubixC,

I'm not sure that's exactly what I need.

If I define the function like this:

def myfunction(self,**kwargs):pass,

I won't be able to make the user call the arguments _a_ and _b_. I won't be able to refer to them in the function either, like this:

def myfunction(self,**kwargs):print a,

because for all I know the user could have called this _a_ anything I have no way of finding out, right?


#19 Emma commented on :

Hi Sofeng and rubixC, I have thought of a way to do what I wanted, but it doesn't look particularly elegant:

def myfunc(self, **kwargs):
    kwargsdict = {}
    expected_args = ["a","b","c"]
    for key in kwargs.keys():
        if key in expected_args:
            kwargsdict[key] = kwargs[key]
        else:
            raise Exception("Unexpected Argument")
    self.__myfunc_help(kwargsdict)

def __myfunc_help(self,a=None,b=None,c=None):
    "real code here"
    pass
#(not tested)

But I don't really like this solution... Emma


#20 Eliot commented on :

Hi Emma,
Thanks for giving us your solution. Have you tried asking on Stack Overflow? They have been helpful to me in the past.


#21 Amit commented on :

That was easy! Thanks!


#22 Joshua commented on :

Thanks for the brief explanation. It was really useful. :-)


#23 İbrahim HIDIR commented on :

Thanks,

I love python magics :)


#24 ces commented on :

Emma --

First, you have to ask yourself why you raising the error is better than letting the system raise the error.

In other words, self.myfunc could consist of just:

self._myfunc_help(**kwargs)

Or, better, the caller could just call _myfunc_help directly.

You don't really need to copy from kwargs to kwargsdict. And you don't need to redundantly specify 'keys' in the for loop:

for key in kwargs:
  if not key in expected:
    raise ...
self._myfnc_help(**kwargs)

You could also play around with things like:

expected = set(['a', 'b', 'c'])
got = set(kwargs.keys())
if bool(got - expected):
   raise ...

#25 Eliot commented on :

ces,
Thank you for your comment. I fixed the formatting of your comment by putting 4 spaces before each line of your code blocks.


#26 Angelica commented on :

Good morning everyone, I have an urgent question regarding *args and there is NOWHERE ELSE a discussion around it...

I need to pass TWO non-keyworded, variable-length argument lists to my class and instance. Somebody said that the word 'args' can be different since we use * in front... so my question is: can I pass something like

(someargs, *args, *myotherargs)?

THANKS!! Angelica.


#27 Angelica commented on :

Excuse me all... the asteriscs * are not apprearing in my previous parenthesis... args should read *args, with asterix myotherargs should read *myotherargs, with asterix... someargs shouldn't have the asterix though..

thanks!


#28 Eliot commented on :

Angelica,
I fixed the formatting of your comment.

Regarding your question, I don't think there is a way to have two variable length argument lists. How about passing two lists as regular positional arguments?


#29 Angelica commented on :

Thanks Eliot, You are right, I tried that option last week. I already created my args as the sum of two lists and it worked... so I use args first as my plain variable length list in one method, and for the next method, I do args = args + moreargs. My class is running now!

Angelica.


#30 Thomas B. Higgins commented on :

This is great; clear as a bell, and not to be found in my Python book! I would be interested in knowing whether there are any wrinkles to keep in mind when using *args and *kwargs with classes, as opposed to functions.


#31 Sibande commented on :

Much love man. This is what I needed and you put it so clear. Thank you


#32 mitjak commented on :

Thanks for the clarification, and I think you've got the most creative and bizarre domain I've seen in a while. Cheerio.


#33 tosh commented on :

Nice - clear and thorough, very helpful, thanks


#34 John commented on :

Conventions aside, must they be named "args" and "kwargs"?

What's the significance of the '*' and '**'. Does the former declare a tuple and latter a dictionary?


#35 Eliot commented on :

John,
"args" and "kwargs" are not the required names-- you can use whatever names you like.

Regarding the significance of * and **, this is the special syntax used to specify variable length arguments.


#36 diman82 commented on :

Great, concise explanation :)


#38 ikani commented on :

Thanks, very helpful! Great blog


#39 George Matter commented on :

great concise explanation. thanks a ton!!


#40 Doug commented on :

Thanks for the simple explanation!

So, I have a very specific question. I have function definition like this:

def my_func(var1='test', *args, **kwargs):

If I call that function like this:

my_func('arg1', 'arg2', 'arg3')

then 'arg1' seems to always be interpreted as the argument to var1 with only 'arg2' and 'arg3' being added to args. But what I wanted was for all of my arguments to be put in args. Is that possible?

I only want to override the default for var1 by explicitly doing so. I guess I wasn't counting on my keyword definition for var1 to also be positional in this case. Any ideas?


#41 Ryan commented on :

Doug,

You should probably not mix positional and keyword arguments as you're doing.

When moving a named argument changes the behavior, that's a clue that something is not right. Consider this,

my_func('arg1', 'arg2', 'arg3', var1='var1_arg')

which will throw a TypeError, because there are multiple values for var1. Ambiguity is bad, and Python doesn't know what to do.

How about doing something like

if not var1: var1='default_value'

in the body? That way you can keep a default value, and change it at will. To make this work, don't specify var1 in the function definition.

-Ryan


#42 Paul commented on :

Thanks. The explanation was very helpful. I had been using my own homebrew method based on function arguments of dictionary (hash) type for passing named arguments. I was forced to do this in Perl as it had nothing of this sort built in. I was glad to find out that Python has this. This is one more reason to switch to Python.


#43 Gurminder commented on :

Thanks, It helped me!


#44 Kilian commented on :

Thank you!

Kilian


#45 Jonas commented on :

Thanks for explaining this; I was getting tired of seeing this all over the Tipfy documentation and not understanding it.


#46 dancebert commented on :

Two thumbs up. Thanks.


#47 James Phillips commented on :

This was very helpful in my work on fitting statistical distributions using scipy, thank you for helping me by posting this. Excellent explanation, well done.

James


#48 Simon Smith commented on :

Thank you for this, your explanation was very useful.


#49 Alfredo commented on :

Wonderful post. Straight to the point! I wish the python doc were that clear.

Thank you


#50 sevalad commented on :

cool. nice and helpfull. thanks.


#51 floerspr4 commented on :

Excuse me all... the asteriscs * are not apprearing in my previous parenthesis... args should read args, with asterix myotherargs should read myotherargs, with asterix... someargs shouldn't have the asterix though..


#52 star_p commented on :

I was glad to find out that Python has this. This is one more reason to switch to Python.


#53 ramber commented on :

This is the perfect tutorial that I have read in my experience!Thanks


#54 Rafe Kettler commented on :

Nice post, very helpful. This was definitely the refresher on this piece of syntax that I needed.


#56 Haiyang commented on :

Thanks for the clear explanation. I was puzzled by this for quite a while.


#57 Tabfugnic commented on :

Thank you so much for the clear explanation. It's been a real life saver.


#58 Dave S commented on :

great description! thanks.


#59 Marcus commented on :

short and clearly, thx!


#60 Naveen.iiit commented on :

Thanks for very Good explanation.


#61 Roman commented on :

Thanks for kwargs...!


#62 Joe commented on :

I'm trying to handle default values for this system, and I've got two ideas, wondering what others think.

defaults = {s0 : v0, s1 : v1} def test(**kwargs): defaults.update(kwargs) do_stuff(defaults)

And then another idea:

defaults = {s0 : v0, s1 : v1} def test(**kwargs): kwargs.setdefault(*defaults.items()) do_stuff(kwargs)

Is there a prettier way?


#64 Eric commented on :

Seriously, awesome. I keep forgetting and keep coming back to this site for the same old explanation.

Thanks for doing this.


#65 Wyatt commented on :

Thanks for all this help. I have been to this site a few times now. This won't be the last.


#66 Alfonso commented on :

Hi, thanks for this great help. Very valuable.


#67 Ken commented on :

Very helpful. Thanks.


#68 Oscar commented on :

You are very good teacher! Thanks!


#69 weigang wei commented on :

thanks a lot


#70 K commented on :

Thanks a lot


#71 jim4499 commented on :

Thank you for the clear & concise explanation.


#72 rekveld commented on :

thanks for the clear explanation, but why do you say **kwargs passes 'a keyworded, variable-length argument list'?

What is that ? It took me some time to figure out that that is actually a Python dictionary. Why not call it that ?


#73 Jeff commented on :

Great explanation! I find myself coming to your blog often.


#74 Bart J commented on :

Great explanation, thank you so much.


#75 Joni j commented on :

Thx, This explanation are real cool!


#76 Bernardo commented on :

Thanks, really helpful.


#77 Travis commented on :

brilliant, thanks a bunch!


#78 Cyril commented on :

thanks!


#79 Chad commented on :

I love straight-to-the-point explanations like this. Thanks!


#81 Weigang commented on :

thanks. excellent explanation!


#82 jeff (different than above) commented on :

I love you. Too much? Then thank you very, very much. I've been trying to find a good explanation for a while now...


#83 bastien commented on :

Just another thanks here :)

It looks like this is one of the basic concepts that many people seem to have a hard time finding either in docs or tutorials.

Beautifully explained here!


#84 Nikhil commented on :

This is the best way to explain any topic. Thanks!


#85 andi commented on :

Very nice explanation of /*, the best i've ever found on the net.


#86 Dave commented on :

Thanks for the explanation, very easy to understand and exactly what I was looking for.


#87 pablo commented on :

Amazing how this post remains so useful even though it has been four years since it saw the light of day.

Thanks, I gained more insight into the use of the kargs argument even though I had already used them. The concepts are similar to the ones used in the command line parsing module argparse for giving instant POSIX behaviour to your python 2.7.x scripts:

http://docs.python.org/library/argparse.html


#88 Piotr commented on :

thanks for this!!! Super easy to understand!


#89 Christopher Paulin commented on :

This article was easy to understand. I saved it for my own reference.


#90 John McCormick commented on :

Must be good to know an article 4 years old is still helping Python novices to this day.

Thanks for this, really useful!


#91 myro commented on :

thank you! simple and neat!


#92 Kyle commented on :

Helpful explanation. Thank you.


#93 Aidan commented on :

Thank you, easy and helpful)


#94 _JF commented on :

Thanks for explanation, I liked your blog and added to my feeds, best regards!


#95 Helen Neely commented on :

This for this simply -yet, comprehensive tutorial on kwargs. Although there are lots of examples all over the web, but none comes close to explaining it as much as you did here.

Nice work.


#96 Deep S commented on :

Hey thanks for the amazing explanation.


#97 Alcides Apaza commented on :

Very easy and straightforward explanation. Thanks! ps: I came here because cs253 on Udacity course