Что означает одиночная (не двойная) звездочка * при распаковке словаря в Python?

Может кто-нибудь объяснить разницу при распаковке словаря с использованием одинарной или двойной звездочки? Вы можете упомянуть их различие при использовании в параметрах функции, только если это уместно здесь, что я так не думаю.

Тем не менее, они могут иметь какое-то значение, потому что они имеют одинаковый синтаксис звездочки.

def foo(a,b)
    return a+b

tmp = {1:2,3:4}
foo(*tmp)        #you get 4
foo(**tmp)       #typeError: keyword should be string. Why it bothers to check the type of keyword? 

Кроме того, почему ключ словаря не может быть нестроковым при передаче в качестве аргументов функции в этой ситуации? Есть ли исключения? Почему они проектируют Python таким образом, потому что компилятор не может определить типы здесь или что-то еще?

Спасибо!

5 ответов

Решение

Когда словари повторяются в виде списков, итерация берет их ключи, например

for key in tmp:
    print(key)

такой же как

for key in tmp.keys():
    print(key)

в этом случае распаковка как *tmp эквивалентно *tmp.keys(), игнорируя значения. Если вы хотите использовать значения, которые вы можете использовать *tmp.values(),

Двойная звездочка используется для определения функции с параметрами ключевых слов, такими как

def foo(a, b):

или же

def foo(**kwargs):

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

def foo(a,b)
   return a+b

tmp = {1:2,3:4}
foo(*tmp)        #you get 4
foo(**tmp) 

В этом случае:
foo(*tmp) имею в виду foo(1, 3)
foo(**tmp) имею в виду foo(1=2, 3=4), что вызовет ошибку, так как 1 не может быть аргументом. Аргумент должен быть строкой и (спасибо @ Alexander Reynolds за указание на это) должен начинаться с символа подчеркивания или алфавита. Аргумент должен быть действительным идентификатором Python. Это означает, что вы не можете даже сделать что-то вроде этого:

def foo(1=2, 3=4):
   <your code>

или же

def foo('1'=2, '3'=4):
   <your code>

Смотрите python_basic_syntax для более подробной информации.

Это расширенная повторяемая распаковка.

>>> def add(a=0, b=0):
...     return a + b
...
>>> d = {'a': 2, 'b': 3}
>>> add(**d)#corresponding to add(a=2,b=3)
5

Для одного *,

def add(a=0, b=0):
    ...     return a + b
    ...
    >>> d = {'a': 2, 'b': 3}
    >>> add(*d)#corresponding to add(a='a',b='b')
    ab

Узнайте больше здесь.

Я думаю, ** двойная звездочка в параметре функции и распаковка словаря означает интуитивно следующим образом:

#suppose you have this function
def foo(a,**b):
    print(a)
    for x in b:
        print(x,"...",b[x])
#suppose you call this function in the following form
foo(whatever,m=1,n=2)   
#the m=1 syntax actually means assign parameter by name, like foo(a = whatever, m = 1, n = 2)
#so you can also do foo(whatever,**{"m":1,"n":2})
#the reason for this syntax is you actually do
**b is m=1,n=2 #something like pattern matching mechanism
so b is {"m":1,"n":2}, note "m" and "n" are now in string form
#the function is actually this:
def foo(a,**b):  # b = {"m":1,"n":2}
    print(a)
    for x in b:  #for x in b.keys(), thanks to @vlizana answer
        print(x,"...",b[x])

Весь синтаксис имеет смысл сейчас. И то же самое для одной звездочки. Стоит только отметить, что если вы используете одну звездочку для распаковки словаря, вы на самом деле пытаетесь распаковать ее списочным способом, и распаковывается только ключ словаря.

[https://docs.python.org/3/reference/expressions.html#calls]

Следствием этого является то, что хотя синтаксис выражения * может появиться после явных аргументов ключевого слова, он обрабатывается перед аргументами ключевого слова (и любыми аргументами выражения ** — см. ниже). Так:

      def f(a, b):
print(a, b)

f(b=1, *(2,))
f(a=1, *(2,))
#Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
#TypeError: f() got multiple values for keyword argument 'a'
f(1, *(2,))
Другие вопросы по тегам