亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python為什么只需一條語句a,b=b,a

發布時間:2021-10-29 20:44:27 來源:億速云 閱讀:163 作者:iii 欄目:編程語言

這篇文章主要講解了“Python為什么只需一條語句a,b=b,a”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Python為什么只需一條語句a,b=b,a”吧!

最顯而易見的例子就是多重賦值,即在一條語句中同時給多個變量賦值:

>>> x, y = 1, 2 >>> print(x, y)  # 結果:1 2

在此例中,賦值操作符“=”號的右側的兩個數字會被存入到一個元組中,即變成 (1,2),然后再被解包,依次賦值給“=”號左側的兩個變量。

如果我們直接寫x = 1,2 ,然后打印出 x,或者在“=”號右側寫成一個元組,就能證實到這一點:

>>> x = 1, 2 >>> print(x)     # 結果:(1, 2) >>> x, y = (1, 2) >>> print(x, y)  # 結果:1 2

一些博客或公眾號文章在介紹到這個特性時,通常會順著舉一個例子,即基于兩個變量,直接交換它們的值:

>>> x, y = 1, 2 >>> x, y = y, x >>> print(x, y) # 結果:2 1

一般而言,交換兩個變量的操作需要引入第三個變量。道理很簡單,如果要交換兩個杯子中所裝的水,自然會需要第三個容器作為中轉。

然而,Python 的寫法并不需要借助中間變量,它的形式就跟前面的解包賦值一樣。正因為這個形式相似,很多人就誤以為 Python  的變量交換操作也是基于解包操作。

但是,事實是否如此呢?

我搜索了一番,發現有人試圖回答過這個問題,但是他們的回答基本不夠全面。(當然,有不少是錯誤的答案,還有更多人只是知其然,卻從未想過要知其所以然)

先把本文的答案放出來吧:Python 的交換變量操作不完全基于解包操作,有時候是,有時候不是!

有沒有覺得這個答案很神奇呢?是不是聞所未聞?!

到底怎么回事呢?先來看看標題中最簡單的兩個變量的情況,我們上dis 大殺器看看編譯的字節碼:

Python為什么只需一條語句a,b=b,a

上圖開了兩個窗口,可以方便比較“a,b=b,a”與“a,b=1,2”的不同:

  • “a,b=b,a”操作:兩個 LOAD_FAST 是從局部作用域中讀取變量的引用,并存入棧中,接著是最關鍵的 ROT_TWO  操作,它會交換兩個變量的引用值,然后兩個 STORE_FAST 是將棧中的變量寫入局部作用域中。

  • “a,b=1,2”操作:第一步 LOAD_CONST 把“=”號右側的兩個數字作為元組放到棧中,第二步 UNPACK_SEQUENCE  是序列解包,接著把解包結果寫入局部作用域的變量上。

很明顯,形式相似的兩種寫法實際上完成的操作并不相同。在交換變量的操作中,并沒有裝包和解包的步驟!

ROT_TWO 指令是 CPython 解釋器實現的對于棧頂兩個元素的快捷操作,改變它們指向的引用對象。

還有兩個類似的指令是 ROT_THREE 和 ROT_FOUR,分別是快捷交換三和四個變量(摘自:ceval.c 文件,最新的 3.9 分支):

Python為什么只需一條語句a,b=b,a

預定義的棧頂操作如下:

Python為什么只需一條語句a,b=b,a

查看官方文檔中對于這幾個指令的解釋,其中 ROT_FOUR 是 3.8 版本新加的:

ROT_TWO  Swaps the two top-most stack items.   ROT_THREE  Lifts second and third stack item one position up, moves top down to position three.   ROT_FOUR  Lifts second, third and forth stack items one position up, moves top down to position four. New in version 3.8.

CPython 應該是以為這幾種變量的交換操作很常見,因此才提供了專門的優化指令。就像 [-5,256] 這些小整數被預先放到了整數池里一樣。

對于更多變量的交換操作,實際上則會用到前面說的解包操作:

Python為什么只需一條語句a,b=b,a

截圖中的 BUILD_TUPLE 指令會將給定數量的棧頂元素創建成元組,然后被 UNPACK_SEQUENCE 指令解包,再依次賦值。

值得一提的是,此處之所以比前面的“a,b=1,2”多出一個 build 操作,是因為每個變量的 LOAD_FAST 需要先單獨入棧,無法直接被組合成  LOAD_CONST 入棧。也就是說,“=”號右側有變量時,不會出現前文中的 LOAD_CONST 一個元組的情況。

最后還有一個值得一提的細節,那幾個指令是跟棧中元素的數量有關,而不是跟賦值語句中實際交換的變量數有關。看一個例子就明白了:

Python為什么只需一條語句a,b=b,a

分析至此,你應該明白前文中的結論是怎么回事了吧?

我們稍微總結一下:

  • Python 能在一條語句中實現多重賦值,這是利用了序列解包的特性

  • Python 能在一條語句中實現變量交換,不需引入中間變量,在變量數少于 4 個時(3.8 版本起是少于 5 個),CPython 是利用了 ROT_*  指令來交換棧中的元素,當變量數超出時,則是利用了序列解包的特性。

  • 序列解包是 Python 的一大特性,但是在本文的例子中,CPython 解釋器在小小的操作中還提供了幾個優化的指令,這絕對會超出大多數人的認知

感謝各位的閱讀,以上就是“Python為什么只需一條語句a,b=b,a”的內容了,經過本文的學習后,相信大家對Python為什么只需一條語句a,b=b,a這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

江城| 光泽县| 泾川县| 胶南市| 镇康县| 和田市| 慈利县| 如皋市| 东丰县| 普安县| 隆尧县| 南投县| 鹤庆县| 鞍山市| 宜州市| 都匀市| 井陉县| 安福县| 南靖县| 桐柏县| 永顺县| 淄博市| 阜新市| 泰州市| 藁城市| 麦盖提县| 启东市| 惠安县| 三门县| 营口市| 文安县| 察哈| 云安县| 通州市| 白河县| 晋江市| 龙陵县| 福安市| 织金县| 迁安市| 曲麻莱县|