[英]What does single(not double) asterisk * means when unpacking dictionary in 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,是因為編譯器無法推斷出這里的類型還是什么?
謝謝!
當字典被迭代為列表時,迭代會獲取它的鍵,例如
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
不能作為參數。 Arg 必須是字符串並且(感謝@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]
這樣做的結果是,盡管 *expression 語法可能出現在顯式關鍵字參數之后,但它在關鍵字參數(以及任何 **expression 參數 - 見下文)之前處理。 所以:
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,))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.