為什么a, b = b, a結果跟你想的不一樣?
我們知道,在Python里面要交換兩個變量,可以用一行代碼實現:
- a, b = b, a
例如:
這個特性,也是很多人介紹Python比其它語言優越的一個案例。
但實際上,這種交換變量的方式,在某些特殊情況下,它的行為可能跟你想要的不一樣。我們來看一個案例。
在一些in-place排序算法中,我們會交換一個列表中兩個索引對應的內容,例如:
這看起來沒有什么問題。更進一步,如果交換的代碼寫為:
- a = [0, 2, 1, 3, 5, 6]
- a[a[1] + 1], a[1] = a[1], a[a[1] + 1]
運行效果如下圖所示:
你肯定覺得顯然是成立的,因為a[1]的值是2,a[1] + 1的值是3,所以上面這段代碼看起來相當于把列表下標為1和下標為3的兩個數字交換順序。也就是把元素2和元素3交換順序。
我們平時一般覺得:a, b = b, a和 b, a = a, b這兩種寫法應該是沒有什么區別的。都是交換兩個變量。但是對于上面這個列表,如果我交換一下逗號左右兩邊的數據,我們再看:
- a = [0, 2, 1, 3, 5, 6]
- a[1], a[a[1] + 1] = a[a[1] + 1], a[1]
運行結果如下:
代碼運行結果跟修改之前竟然不一樣。
之所以會出現這種情況,是因為這種交換兩個值的方式,雖然只有一行代碼,但是 Python 在執行的時候,其實是分成兩步來走的。
對于a[1], a[a[1] + 1] = a[a[1] + 1], a[1],首先,Python 執行的是a[1] = a[a[1] + 1],也就是a[1] = a[3]。這個時候,列表變成了[0, 3, 1, 3, 5, 6]。然后,Python 再執行a[a[1] + 1] = a[1],注意這個時候的a[1]的值已經是3了。也就變成了a[4] = a[1]。所以原來a[4]位置的5就被a[1]位置的數字3覆蓋了。所以最終的結果就變成了[0, 3, 1, 3, 2, 6]。
所以,在使用 Python 這種一行交換兩個變量的語法糖的時候,如果需要對列表里面的元素進行交換,請一定要小心,不要由于執行順序的問題導致結果跟想要的不一致。
本文轉載自微信公眾號「未聞Code」,可以通過以下二維碼關注。轉載本文請聯系未聞Code公眾號。