簡體   English   中英

解包參數:只有命名參數可以跟*表達式

[英]Unpacking arguments: only named arguments may follow *expression

以下在Python中運行得非常好:

def f(x,y,z): return [x,y,z]

a=[1,2]

f(3,*a)

的元素a得到解壓縮,如果你有一個像把它稱為f(3,1,2)並返回[3,1,2] 精彩!

但是我無法將a的元素解壓縮到兩個參數中:

f(*a,3)

我沒有像f(1,2,3)那樣調用它,而是“SyntaxError:只有命名參數才能跟*表達式”。

我只是想知道為什么它必須是這樣的,如果有任何聰明的技巧我可能不會意識到將數組解壓縮到參數列表的任意部分而不訴諸臨時變量。

正如Raymond Hettinger的回答所指出的,這可能會在Python 3中發生變化, 這是一個相關的提案 ,已被接受。 特別是與當前問題有關,這是對該提案的可能變更之一:

僅允許星號表達式作為exprlist中的最后一項。 這將簡化解包代碼並允許為星號表達式分配迭代器。 這種行為被拒絕了,因為它太令人驚訝了。

所以有解包函數參數限制的實現原因,但確實有點令人驚訝!

與此同時,這是我正在尋找的解決方法,回顧過去有點明顯:

f(*(a+[3]))

感謝PEP 448 - 附加拆包概括

f(*a, 3)

現在從Python 3.5開始接受的語法 同樣,您可以在任何地方使用雙星**關鍵字參數解壓縮,並且可以多次使用其中一個。

並不一定是這樣的。 Guido認為合情合理。

在Python 3中,解包的規則已經有所自由:

>>> a, *b, c = range(10)
>>> a
0
>>> b
[1, 2, 3, 4, 5, 6, 7, 8]
>>> c
9

根據Guido是否認為它會改善語言,自由化也可以擴展到功能論點。

有關Python 3更改規則的原因的一些想法,請參閱有關擴展可迭代解包的討論。

f期望3個參數( xyz ,按此順序)。

假設L = [1,2] 當你調用f(3, *L) ,python在幕后做的是調用f(3, 1, 2) ,而不知道L的長度。

那么如果L代替[1,2,3]會發生什么?

然后,當你調用f(3, *L) ,你最終會調用f(3,1,2,3) ,這將是一個錯誤,因為f期待正好3個參數,你給它4。

現在,假設L=[1,2]1. Look at what happens when you call L=[1,2]1. Look at what happens when you call f` L=[1,2]1. Look at what happens when you call

>>> f(3,*L) # works fine
>>> f(*L) # will give you an error when f(1,2) is called; insufficient arguments

現在,你隱含地知道你何時調用f(*L, 3)將3分配給z ,但是python不知道。 它只知道f的輸入的最后j元素將由L的內容定義。 但由於它不知道len(L)的值,因此無法假設f(*L,3)是否具有正確數量的參數。

然而,這不是f(3,*L) 在這種情況下,python知道除了第一個參數之外的所有參數都將由L的內容定義。

但是如果你有參數f(x=1, y=2, z=3) ,則首先綁定按名稱分配的參數。 只有這樣才能限制位置參數。 所以你做f(*L, z=3) 在這種情況下, z首先綁定到3 ,然后綁定其他值。

現在有趣的是,如果你做f(*L, y=3) ,這會給你一個錯誤,試圖分配給y兩次(一次用關鍵字,再一次用位置)

希望這可以幫助

尼斯。 這也適用於元組。 不要忘記逗號:

a = (1,2)
f(*(a+(3,)))

如果你使用f(*a, 3) ,你可以使用f(*a, z=3) ,它不知道如何解壓縮參數,因為你提供了2個參數而2是第二個參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM