# [Tutor] the "**" operator?

Hugo Arts hugo.yoshi at gmail.com
Fri Dec 10 20:48:56 CET 2010

```On Fri, Dec 10, 2010 at 8:14 PM, Alex Hall <mehgcap at gmail.com> wrote:
> Hi all,
> I was googling a way to do something like
>

http://docs.python.org/library/stdtypes.html#dict.update

> and someone on a forum recommends this:
> What is the ** doing here? I tried to look it up, but Google seems to
> ignore it since it is punctuation. The poster on the forum says it
> will put all elements of additionaldict in mydict that are not already
> in mydict, which is the behavior I am looking for, but I am not sure
> why this would be so. TIA.
>

The * and **, when calling functions, are what's called extended
calling syntax. It's a bit hard to explain, so I'm going to do a sort
of clarify by example here:

>>> def f(a, b, c):
...     print a, b, c
...
>>> f(1, 2, 3)
1 2 3
>>> a = [1, 2, 3]
>>> f(*a)
1 2 3
>>> b = {'a': 2, 'b': 1, 'c': 3}
>>> f(*b)
a c b
>>> f(**b)
2 1 3

In short, if a = [1, 2, 3], f(*a) is the same as f(1, 2, 3). if b =
{'a': 2, 'b': 1, 'c': 3}, then f(**b) is the same as f(a=2, b=1, c=3).

The * will iterate over its argument, and supply the resulting values
as arguments to the function (iterating over a dict will return its
keys, which is what you see with f(*b) here). ** requires a mapping
type, and supplies the keys and values to the function as keyword
arguments.

* and ** are very flexible, and you can use them alongside with
regular arguments:

>>> f(1, *[2, 3])
1 2 3
>>> f(1, **{'b': 2, 'c': 3})
1 2 3

* and ** also have uses in function definition, where they sort of do
the reverse. They can capture any number of regular or keyword
arguments in a tuple or dictionary:

>>> def f(*args, **kwargs):
...     print args, kwargs
...
>>> f()
() {}
>>> f(1, 2, 3)
(1, 2, 3) {}
>>> f(1, 2, 3, a=4, b=5)
(1, 2, 3) {'a': 4, 'b': 5}
>>> f(a=4, b=5)
() {'a': 4, 'b': 5}

Like with function calls, you can mix up regular arguments and */**
arguments, as long as the resulting function is unambiguous:

>>> def f(a, *args, **kwargs):
...     print a, args, kwargs
...
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes at least 1 argument (0 given)
>>> f(1)
1 () {}
>>> f(1, 2, 3)
1 (2, 3) {}
>>> f(1, 2, 3, b=4, c=5)
1 (2, 3) {'c': 5, 'b': 4}
```