這種機制的工作方式是兩個特性的組合——形成隐式元組和元組/清單解包。
當您執行something = x, y操作時,Python将隐式地建立由x和y兩個元素組成的tuple(一種不可變清單)。是以,以下兩行代碼完全等效:something = x, y
something = (x, y)
當然,元組可以包含兩個以上的元素:something = a, b, c, d, e
something = (a, b, c, d, e)
此功能的預期用例是為了使從函數傳回多個值這樣的操作更容易/更清晰:def foo():
return "hello", "world"
第二個特性是tuple/list解包。每當左邊有一系列變量,而另一邊有任何類型的清單、元組或其他集合時,Python都會嘗試将右邊的每個元素與左邊的元素比對起來:>>> a, b, c = [11, 22, 33]
>>> print(a)
11
>>> print(b)
22
>>> print(c)
33
如果有幫助,那麼a, b, c = [11, 22, 33]行與執行以下操作基本相同:temp = [11, 22, 33]
a = temp[0]
b = temp[1]
c = temp[2]
注意,右邊可以是任何類型的集合,而不僅僅是元組或清單。是以下面的代碼是有效的:>>> p, q = "az"
>>> print(p + " " + q)
a z
>>>
>>> s, t = {'cat': 'foo', 'dog': 'bar'}
>>> print(s + " " + t)
cat dog
(盡管如此,由于Python中的詞典沒有義務按照任何特定的順序排列,而且由于密鑰的順序可以自由地進行置亂,是以解包它們可能不會有用,因為每次都可能得到不同的結果。)
如果集合中的變量數和元素數不比對,Python将抛出異常:>>> a, b = (1, 2, 3)
Traceback (most recent call last):
File "", line 1, in
ValueError: too many values to unpack (expected 2)
>>> a, b, c = (1, 2)
Traceback (most recent call last):
File "", line 1, in
ValueError: need more than 2 values to unpack
這意味着如果我們從上面調用foo函數并執行以下操作:>>> x, y = foo()
…變量x等于字元串"hello",變量y等于字元串"world"。
是以最終,這意味着你最初的代碼片段:x = "salil"
y = "Ajay"
y, x = x, y
…在邏輯上等同于:x = "salil"
y = "Ajay"
temp = (x, y) # evaluates to ("salil", "Ajay")
y, x = temp
……在邏輯上更是等同于:x = "salil"
y = "Ajay"
temp = (x, y) # evaluates to ("salil", "Ajay")
y = temp[0]
x = temp[1]
請注意,您可以認為這兩個操作是分别進行的。首先形成元組并對其求值,然後将元組解壓回變量中。最終的效果是兩個變量的值是互換的。
(然而,事實證明,CPython解釋器(Python的原始和“标準”實作)在這裡做了一些優化:它将優化交換,而不會進行完整的元組解包——見下面的注釋)。我不确定其他Python實作是否也會這樣做,盡管我懷疑它們可能會這樣做。在任何情況下,這種優化都是特定于實作的,并且獨立于Python語言本身的設計。)