Saltycrane logo

SaltyCrane Blog

Notes on Python, Django, 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

97 Comments — feed icon Comments feed for this post


#1 Skawaii commented on 2008-02-13:

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


#2 Julien commented on 2008-05-16:

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


#3 Dmitry commented on 2008-10-28:

Thanks for your explanation.


#4 mike commented on 2008-10-29:

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 2008-10-29:

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


#6 Katja commented on 2008-10-31:

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


#7 Volkan commented on 2008-11-13:

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


#8 Richie commented on 2008-11-22:

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 2009-01-13:

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 2009-01-20:

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 2009-02-16:

Excellent, clear explanation. Thanks for the post.


#12 Emma commented on 2009-04-08:

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 2009-04-15:

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 2009-05-11:

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

Python is so cool. :-)


#15 rubixC commented on 2009-05-13:

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 2009-05-15:

Thanks!


#17 Nicolas commented on 2009-05-19:

I second all that! Thanks for the explanation!


#18 Emma commented on 2009-05-20:

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 2009-05-21:

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 2009-05-22:

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 2009-06-01:

That was easy! Thanks!


#22 Joshua commented on 2009-06-28:

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


#23 İbrahim HIDIR commented on 2009-07-27:

Thanks,

I love python magics :)


#24 ces commented on 2009-08-18:

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 myfunchelp 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 2009-08-19:

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 2009-08-27:

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 2009-08-27:

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 2009-08-27:

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 2009-08-31:

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 2009-09-02:

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 2009-09-06:

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


#32 mitjak commented on 2009-10-02:

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 2009-11-05:

Nice - clear and thorough, very helpful, thanks


#34 John commented on 2009-12-09:

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 2009-12-09:

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 2010-01-17:

Great, concise explanation :)


#37 David Underhill commented on 2010-01-18:

Thanks for the concise tutorial. Perfect.


#38 ikani commented on 2010-01-19:

Thanks, very helpful! Great blog


#39 George Matter commented on 2010-01-29:

great concise explanation. thanks a ton!!


#40 Doug commented on 2010-02-03:

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 2010-02-09:

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 2010-02-22:

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 2010-03-16:

Thanks, It helped me!


#44 Kilian commented on 2010-05-16:

Thank you!

Kilian


#45 Jonas commented on 2010-08-27:

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


#46 dancebert commented on 2010-09-24:

Two thumbs up. Thanks.


#47 James Phillips commented on 2010-10-01:

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 2010-10-13:

Thank you for this, your explanation was very useful.


#49 Alfredo commented on 2010-11-01:

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

Thank you


#50 sevalad commented on 2010-11-11:

cool. nice and helpfull. thanks.


#51 floerspr4 commented on 2010-11-18:

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 2010-11-18:

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


#53 ramber commented on 2010-11-18:

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


#54 Rafe Kettler commented on 2010-11-23:

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


#55 reg3x commented on 2010-12-02:

Very educational .. i just took this post , translated it to spanish and did a few comments, you can see it on:

http://diegoaguilera.com/como-usar-args-y-kwargs-en-python.html


#56 Haiyang commented on 2011-01-02:

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


#57 Tabfugnic commented on 2011-01-25:

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


#58 Dave S commented on 2011-02-04:

great description! thanks.


#59 Marcus commented on 2011-03-02:

short and clearly, thx!


#60 Naveen.iiit commented on 2011-03-22:

Thanks for very Good explanation.


#61 Roman commented on 2011-03-25:

Thanks for kwargs...!


#62 Joe commented on 2011-03-27:

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?


#63 Prasanna S commented on 2011-05-09:

Great job, thanks.


#64 Eric commented on 2011-07-31:

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 2011-08-03:

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 2011-08-09:

Hi, thanks for this great help. Very valuable.


#67 Ken commented on 2011-08-24:

Very helpful. Thanks.


#68 Oscar commented on 2011-09-05:

You are very good teacher! Thanks!


#69 weigang wei commented on 2011-10-13:

thanks a lot


#70 K commented on 2011-10-19:

Thanks a lot


#71 jim4499 commented on 2011-10-26:

Thank you for the clear & concise explanation.


#72 rekveld commented on 2011-10-28:

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 2011-11-05:

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


#74 Bart J commented on 2011-12-02:

Great explanation, thank you so much.


#75 Joni j commented on 2011-12-20:

Thx, This explanation are real cool!


#76 Bernardo commented on 2011-12-23:

Thanks, really helpful.


#77 Travis commented on 2012-01-15:

brilliant, thanks a bunch!


#78 Cyril commented on 2012-01-24:

thanks!


#79 Chad commented on 2012-01-27:

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


#80 Crittercism commented on 2012-02-01:

Great explanation!


#81 Weigang commented on 2012-02-15:

thanks. excellent explanation!


#82 jeff (different than above) commented on 2012-02-23:

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 2012-02-27:

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 2012-05-02:

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


#85 andi commented on 2012-05-07:

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


#86 Dave commented on 2012-05-20:

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


#87 pablo commented on 2012-07-13:

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 2012-07-22:

thanks for this!!! Super easy to understand!


#89 Christopher Paulin commented on 2012-08-06:

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


#90 John McCormick commented on 2012-09-05:

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 2012-09-17:

thank you! simple and neat!


#92 Kyle commented on 2012-12-22:

Helpful explanation. Thank you.


#93 Aidan commented on 2012-12-29:

Thank you, easy and helpful)


#94 _JF commented on 2012-12-30:

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


#95 Helen Neely commented on 2013-08-02:

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 2013-10-19:

Hey thanks for the amazing explanation.


#97 Alcides Apaza commented on 2013-12-30:

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

Post a comment

Required
Required, but not displayed
Optional

Format using Markdown. (No HTML.)
  • Code blocks: prefix each line by at least 4 spaces or 1 tab (and a blank line before and after)
  • Code span: surround with backticks
  • Blockquotes: prefix lines to be quoted with >
  • Links: <URL>
  • Links w/ description: [description](URL)
Created with Django | Hosted by Linode