# [Tutor] (*args, **kwargs)

Jordan Greenberg jordangreenberg at gmail.com
Fri Aug 4 18:38:54 CEST 2006

```Matt Williams wrote:
> Dear All,
>
> I have learnt to do bits of python, but one of the things I cannot get
> my head around is the *args, **kwargs syntax.
>
> I have tried reading stuff on the web, and I have a copy of the python
> cookbook (which uses it as a recipe early on) but I still don't
> understand it.
>
> Please could someone explain _very_ slowly?
>
> Apologies for the gross stupidity,
>
> Matt

Basically, *args and **kwargs allows you to collect arguments.
Normally, you'd do something like:
*args collects any arguments (other then the positional ones) into a
list, and **kwargs collects arguments into a dictionary.
In [6]: def foo(a, b, c):
...:         print a, b, c
...:

In [7]: foo(1, 2, 3)
1 2 3

but, say you wanted to make it so it could accept any number of
arguments, you could use *args like so:
In [4]: def foo(*args):
...:         print args
...:         for each in args:
...:                 print each
...:

In [5]: foo(1, 2, 3, 4)
(1, 2, 3, 4)
1
2
3
4

Notice how all the parameters i passed to foo are collected in the list
args.

**kwargs collects arguments of the form key=value into a dictionary,
like so:

In [15]: def foo(**kwargs):
....:        print kwargs
....:

In [16]: foo(name="Jordan", email="jordangreenberg at gmail.com")
{'name': 'Jordan', 'email': 'jordangreenberg at gmail.com'}

Your functions can then use the list/dictionary as normal.
You can also use these in conjunction with normal positional parameters:

In [27]: def foo(a, b, c, *args, **kwargs):
....:        print "Positional arguments:"
....:        print a, b, c
....:        print "Non-positional argument list:"
....:        print args
....:        for each in args:
....:                print each
....:        print "Keyword argument list:"
....:        print kwargs
....:        for key in kwargs.keys():
....:                print "Key: ", key
....:                print "Data: ", kwargs[key]
....:

In [28]: foo(1, "monkey", 7.5, 10, 11, 12, name="jordan",
email="jordangreenberg at gmail.com")
Positional arguments:
1 monkey 7.5
Non-positional argument list:
(10, 11, 12)
10
11
12
Keyword argument list:
{'name': 'jordan', 'email': 'jordangreenberg at gmail.com'}
Key:  name
Data:  jordan
Key:  email
Data:  jordangreenberg at gmail.com

So, to summarize, *args and **kwargs are basically there so you can
build your functions so that they can accept a variable number of arguments.