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?
1

4 Answers 4

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)
Sign up to request clarification or add additional context in comments.

Comments

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/

Comments

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.

Comments

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.

2 Comments

Does foo(1, 2, 3) really produce a list for you? It gives a tuple here.
Sorry, hasty there. It is actually a tuple. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.