Подтвердить что ты не робот

Лямбда и функции в Python

У меня есть два вопроса для начинающих

  • Что означает *z или *foo или **foo означает функцию в Python.
  • Это работает - a = lambda *z :z Но это не - a = lambda **z: z. Потому что он должен принимать 0 аргументов. Что это значит?
4b9b3361

Ответ 1

*z и **z в Python относятся к args и kwargs. args - позиционные аргументы, а kwargs - аргументы ключевых слов. lambda **z не работает в вашем примере, потому что z не является аргументом ключевого слова: он просто позиционный. Сравните эти разные результаты:

    >>> 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)

Ответ 3

Когда вы видите что-то вроде def foo(*args) или def foo(**kwargs), они говорят вам, что они ждут чего-то большего, чем один аргумент. Они ожидают несколько аргументов или несколько названных аргументов. Часто, однако, вы видите следующее:

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

Что говорит вам, что они ожидают хотя бы пунктов 1, 2 и 3, но "args" и "kwargs" являются необязательными параметрами.

Чтобы ответить на ваш вопрос относительно a = lambda **z: z, попробуйте передать "список названных аргументов" следующим образом:

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

Выход будет словарем, как вы нечаянно определили. Именованные списки аргументов - это, по сути, словари.

Ответ 4

*args может использоваться для того, чтобы функция принимала произвольное количество аргументов. **kwargs может использоваться, чтобы заставить функцию принимать произвольные аргументы ключевых слов. Это означает, что:

>>> 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)

Последняя ошибка возникает, потому что bar может принимать только аргументы ключевых слов.