1. 程式人生 > >你不知道的Python(2)

你不知道的Python(2)

今天我們來看看Python的另一個隱藏特性。

首先,我們先來看看如下一段程式碼:

在上面一段程式碼中,我們先宣告一個list物件,名叫array,然後用一個生成器表示式賦值給g,最後將array重新賦值,那麼如果我們把g的內容打印出來會是什麼樣的呢?

在列印g之前我們可以分析一下這個生成器表示式是要做什麼:首先x for x in array是將array中的元素全都取出來,然後if array.count(x)是判斷取出來的x的數量是否大於0,如果大於0,則此x滿足條件可以新增到g中。那麼照此分析來看,打印出來的g中應該包含1、3、5三個元素。

可是果真如此嗎?看一下打印出來的g的結果:

我們驚奇的發現,打印出來的g的結果中只含有3,而不含有我們之前推測的還應該包含的元素1和元素3.

這是為什麼呢?原來啊,這是因為:在生成器表示式中, in 子句在宣告時執行, 而條件子句則是在執行時執行

這就導致在第一條語句中,array的內容實際為[1,3,5],在第二條語句中,x for x in array在此生成器表示式宣告時就會執行,所以x for x in array 實際得到的結果為[1,3,5],但是此時array.count(x)>0還不會執行。然後在第三條語句中array的內容被更新為[2,3,4]。當我們在列印g的時候,if array.count(x)>0才會執行,但是此時array的內容已經更新為[2,3,4],而x for x in array 的內容為[1,3,5],所以綜合二者看來,滿足count(x)>0的元素就只有3。因此最終列印g的結果為[3]。

接下來我們看一下另一個有趣的現象:

根據上面程式碼,我們可以顯然知道g_1的內容應該為[1,2,3],這是因為array_1在被重新賦值的時候,實際上是被繫結到一個新物件[1,2,3,4],而因為生成器表示式中的in子句是在宣告時執行,所以其指向的物件實際還是原來的舊物件[1,2,3]。

我們再看一段程式碼:

在此段程式碼中我們卻發現和上一段程式碼得到的結果不相同,很顯然,問題就出現在第三條語句的切片賦值上。原來啊,切片賦值的時候會將舊物件一起更新,因此生成器表示式g_2和array_2均是指向同一物件,所以打印出的結果為[1,2,3,4]。

好了,這就是在這裡要跟大家分享的關於python的一個小特性。

大家可以去多多支援原作者,原連結如下:https://github.com/leisurelicht/wtfpython-cn#structure-of-the-examples%E7%A4%BA%E4%BE%8B%E7%BB%93%E6%9E%84