16

I know what the meaning of an asterisk is in a function definition in Python.

I often, though, see asterisks for calls to functions with parameters like:

def foo(*args, **kwargs):
    first_func(args, kwargs)
    second_func(*args, **kwargs)

What is the difference between the first and the second function call?

QuantumFool
  • 609
  • 3
  • 10
  • 29
Robert Moon
  • 1,025
  • 10
  • 17
  • 1
    asterisk take variables out of brackets :) – LittleQ Jul 03 '15 at 03:27
  • possible duplicate of [Understanding kwargs in Python](http://stackoverflow.com/questions/1769403/understanding-kwargs-in-python) –  Jul 03 '15 at 03:33

3 Answers3

24

Let args = [1,2,3]:

func(*args) == func(1,2,3) - variables are unpacked out of list (or any other sequence type) as parameters

func(args) == func([1,2,3]) - the list is passed

Let kwargs = dict(a=1,b=2,c=3):

func(kwargs) == func({'a':1, 'b':2, 'c':3}) - the dict is passed

func(*kwargs) == func(('a','b','c')) - tuple of the dict's keys (in random order)

func(**kwargs) == func(a=1,b=2,c=3) - (key, value) are unpacked out of the dict (or any other mapping type) as named parameters

LittleQ
  • 1,860
  • 1
  • 12
  • 14
10

The difference is how the arguments are passed into the called functions. When you use the *, the arguments are unpacked (if they're a list or tuple)—otherwise, they're simply passed in as is.

Here's an example of the difference:

>>> def add(a, b):
...   print a + b
...
>>> add(*[2,3])
5
>>> add([2,3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() takes exactly 2 arguments (1 given)
>>> add(4, 5)
9

When I prefixed the argument with *, it actually unpacked the list into two separate arguments, which were passed into add as a and b. Without it, it simply passed in the list as a single argument.

The same is the case for dictionaries and **, except they're passed in as named arguments rather than ordered arguments.

>>> def show_two_stars(first, second='second', third='third'):
...    print "first: " + str(first)
...    print "second: " + str(second)
...    print "third: " + str(third)
>>> show_two_stars('a', 'b', 'c')
first: a
second: b
third: c
>>> show_two_stars(**{'second': 'hey', 'first': 'you'})
first: you
second: hey
third: third
>>> show_two_stars({'second': 'hey', 'first': 'you'})
first: {'second': 'hey', 'first': 'you'}
second: second
third: third
jdotjdot
  • 16,134
  • 13
  • 66
  • 118
0
def fun1(*args):
    """ This function accepts a non keyworded variable length argument as a parameter.
    """
    print args        
    print len(args)


>>> a = []

>>> fun1(a)
([],)
1
# This clearly shows that, the empty list itself is passed as a first argument. Since *args now contains one empty list as its first argument, so the length is 1
>>> fun1(*a)
()
0
# Here the empty list is unwrapped (elements are brought out as separate variable length arguments) and passed to the function. Since there is no element inside, the length of *args is 0
>>>
  • I think your answer would be more clear if you'd added some values to `a` – winklerrr May 19 '17 at 08:49
  • That example was to show the way the unpacking of args works. If you have an element added to 'a' and passed to args without unpacking, then the length of args would be 1. For the first case it would be (['some val'],) and for the second case it would be ('some val',) – user2126456 May 20 '17 at 04:45
  • It would look great if you added your examples in the previous comment to your answer. :-) – TrebledJ Jan 20 '19 at 17:19