16

I have beginner two questions

  1. What does *z or *foo or **foo mean regarding function in Python.
  2. This works - a = lambda *z :z But this does not - a = lambda **z: z. Because it is supposed to take 0 arguments. What does this actually mean?
user
  • 5,370
  • 8
  • 47
  • 75
Sumod
  • 3,806
  • 9
  • 50
  • 69

4 Answers4

20

*z and **z in Python refer to args and kwargs. args are positional arguments and kwargs are keyword arguments. lambda **z doesn't work in your example because z isn't a keyword argument: it's merely positional. Compare these different results:

    >>> a = lambda z: z
    >>> b = lambda *z: z
    >>> c = lambda **z: z
    >>> a([1,2,3])
    [1, 2, 3]
    >>> b([1,2,3])
    ([1, 2, 3],)
    >>> c([1,2,3]) # list arg passed, **kwargs expected
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: <lambda>() takes exactly 0 arguments (1 given)
    >>> c(z=[1,2,3]) # explicit kwarg
    {'z': [1, 2, 3]}
    >>> c(x=[1,2,3]) # explicit kwarg
    {'x': [1, 2, 3]}
    >>> c({'x':[1,2,3]}) # dict called as a single arg
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: <lambda>() takes exactly 0 arguments (1 given)
    >>> c(**{'x':[1,2,3]}) # dict called as **kwargs
    {'x': [1, 2, 3]}
    >>> b(*[1,2,3]) # list called as *args
    (1, 2, 3)
kojiro
  • 74,557
  • 19
  • 143
  • 201
4

Check out the link its a good blog post on How to use *args and **kwargs in Python http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/

Anuj
  • 9,222
  • 8
  • 33
  • 30
4

When you see something like def foo(*args) or def foo(**kwargs) they're telling you they're expecting something more than a single argument. They're expecting several arguments or several named arguments. Often, however, you see this:

def foo(item1, item2, item3, *args, **kwargs)

Which tells you that they're expecting at least item's 1, 2, and 3 but "args" and "kwargs" are optional parameters.

To answer your question regarding a = lambda **z: z try passing in a "named argument list" like so:

> a = lambda **z:z
> a(b=1, c=2)
>> {b : 1, c : 2}

The output will be a dictionary, just as you inadvertently defined. Named argument lists are, in essence, dictionaries.

wheaties
  • 35,646
  • 15
  • 94
  • 131
2

*args can be used to make a function take an arbitrary number of arguments. **kwargs can be used to make a function take arbitrary keyword arguments. This means that:

>>> foo = lambda *args: args
>>> bar = lambda **kwargs: kwargs
>>> foo(1,2,3)
(1,2,3)
>>> bar(asdf=1)
{'asdf':1}
>>> bar(1,2,3)
TypeError: <lambda>() takes exactly 0 arguments (3 given)

The last error happens because bar can only take keyword arguments.

Björn Pollex
  • 75,346
  • 28
  • 201
  • 283