所有代碼均來自于Python 2.7 版本
對于交換兩個值的操作,可能大多數(shù)之前不具備Python基礎的童鞋比較容易寫出以下代碼:
>>> tmp = x
>>> x = y
>>> y = tmp
顯然,這樣寫很不Pythonic,它的確可以工作,但稱不上簡潔有效。
#在Python中更常見的寫法
>>> x, y = y, x
簡潔性可以一目了然,那效率又如何呢?
>>> from timeit import Timer
>>> Timer('tmp = x;x = y;y = tmp','x = 2; y = 4').time()
0.0300285 #根據(jù)運行環(huán)境不同,結果可能會有差異
>>> Timer('x, y = y, x', 'x = 2; y = 4').timeit()
0.0265907
雖然差距不大,但是還是有一點點差距的。(差距不明顯是因為只是一個簡單的賦值語句,加上計算機的計算速度與日俱增)
那么,在x, y = y, x的背后都發(fā)生了些什么呢?
一般情況下Python語句是從左到右解析一個語句的,但在賦值操作的時候,因為是右值具有更高的計算優(yōu)先級,所以需要從右向左解析。
對于x, y = y, x,它的執(zhí)行順序如下:
- 先計算右值
y , x(這里是簡單的原值,但可能會有表達式或者函數(shù)調用的計算過程), 在內存中創(chuàng)建元組(tuple),存儲y, x分別對應的值; - 計算左邊的標識符,元組被分別分配給左值,通過解包(unpacking),元組中第一個標示符對應的值(y),分配給左邊第一個標示符(x),元組中第二個標示符對應的值(x),分配給左邊第二個標示符(y),完成了
x和y的值交換。
需要注意的是當左右值和標識符的數(shù)量不等時會出現(xiàn)ValueError:
>>> x, y = 1, 2
>>> x, z = y, x, 3
ValueError: too many values to unpack
>>> y, x , a= x, y
ValueError: need more than 2 values to unpack
而當左值只有一個變量的時候,默認將右值打包(pack)成一個元組(tuple)傳給右值。
>>> x = 1, 2
>>> x
(1, 2)