python 實(shí)現(xiàn)兩個(gè)變量值進(jìn)行交換的n種操作
python 兩個(gè)變量值交換
方法一:
c = 0 c= a a= b b= c
方法二:
a,b = b,a
這是python的基本方法
方法三:(只用兩個(gè)變量實(shí)現(xiàn))
a = a+b b = a-b a = a-b
python兩個(gè)數(shù)值互換(淺析a,b=b,a原理)
python交換兩個(gè)值得方法非常簡(jiǎn)單,即a,b=b,a,一步操作就交換了兩個(gè)值,那么這是為什么呢?
真相:
Python的變量并不直接存儲(chǔ)值,而只是引用一個(gè)內(nèi)存地址,交換變量時(shí),只是交換了引用的地址。
先看下面這段程序:
import dis
def func(a,b):
a,b=b,a
print(a,b)
a=10
b=20
func(a,b)
dis.dis(func)
一般來(lái)說(shuō)一個(gè)Python語(yǔ)句會(huì)對(duì)應(yīng)若干字節(jié)碼指令,Python的字節(jié)碼是一種類似匯編指令的中間語(yǔ)言,但是一個(gè)字節(jié)碼指令并不是對(duì)應(yīng)一個(gè)機(jī)器指 令(二進(jìn)制指令),而是對(duì)應(yīng)一段C代碼,而不同的指令的性能不同,所以不能單獨(dú)通過(guò)指令數(shù)量來(lái)判斷代碼的性能,而是要通過(guò)查看調(diào)用比較頻繁的指令的代碼來(lái) 確認(rèn)一段程序的性能。
一個(gè)Python的程序會(huì)有若干代碼塊組成,例如一個(gè)Python文件會(huì)是一個(gè)代碼塊,一個(gè)類,一個(gè)函數(shù)都是一個(gè)代碼塊,一個(gè)代碼塊會(huì)對(duì)應(yīng)一個(gè)運(yùn)行的上下文環(huán)境以及一系列的字節(jié)碼指令。
dis的作用
dis模塊主要是用來(lái)分析字節(jié)碼的一個(gè)內(nèi)置模塊,經(jīng)常會(huì)用到的方法是dis.dis([bytesource]),參數(shù)為一個(gè)代碼塊,可以得到這個(gè)代碼塊對(duì)應(yīng)的字節(jié)碼指令序列。
代碼輸出結(jié)果

其中只看前面為12的結(jié)果就行了(在我的編譯器里,交換的那一行代碼在第12行)
可以看出主要是ROT_TWO指令的功勞:
查閱python文檔可以知道有ROT_TWO (源碼1398行),ROT_THREE(源碼1406行), ROT_FOUR這樣的指令,可以直接
交換兩個(gè)變量、三個(gè)變量、四個(gè)變量的值
在python3.4的源碼中查閱ceval.c文件可以看到:
TARGET(ROT_TWO) {
PyObject *top = TOP();
PyObject *second = SECOND();
SET_TOP(second);
SET_SECOND(top);
FAST_DISPATCH();
}
TARGET(ROT_THREE) {
PyObject *top = TOP();
PyObject *third = THIRD();
SET_SECOND(third);
FAST_DISPATCH();
}
附:python值的交換
變量的每一次初始化,都開辟了一個(gè)新的空間,將新內(nèi)容的地址賦值給變量。對(duì)于下圖來(lái)說(shuō),我們重復(fù)的給str1賦值,其實(shí)在內(nèi)存中的變化如圖:

從上圖我們可以看出,str1在重復(fù)的初始化過(guò)程中,是因?yàn)閟tr1中存儲(chǔ)的元素地址由'hello world'的地址變成了'new hello world'的。
對(duì)于復(fù)雜的數(shù)據(jù)類型來(lái)說(shuō),改變其內(nèi)部的值對(duì)于變量的影響:


當(dāng)對(duì)列表中的元素進(jìn)行一些增刪改的操作的時(shí)候,是不會(huì)影響到lst1列表本身對(duì)于整個(gè)列表地址的,只會(huì)改變其內(nèi)部元素的地址引用。
可是當(dāng)我們對(duì)于一個(gè)列表重新初始化(賦值)的時(shí)候,就給lst1這個(gè)變量重新賦予了一個(gè)地址,覆蓋了原本列表的地址,這個(gè)時(shí)候,lst1列表的內(nèi)存id就發(fā)生了改變。上面這個(gè)道理用在所有復(fù)雜的數(shù)據(jù)類型中都是一樣的。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python實(shí)現(xiàn)控制臺(tái)中的進(jìn)度條功能代碼
下面小編就為大家分享一篇Python實(shí)現(xiàn)控制臺(tái)中的進(jìn)度條功能代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
python內(nèi)置HTTP Server如何實(shí)現(xiàn)及原理解析
這篇文章主要為大家介紹了python內(nèi)置HTTP Server如何實(shí)現(xiàn)及原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
pycharm利用pyspark遠(yuǎn)程連接spark集群的實(shí)現(xiàn)
由于工作需要,利用spark完成機(jī)器學(xué)習(xí)。因此需要對(duì)spark集群進(jìn)行操作。所以利用pycharm和pyspark遠(yuǎn)程連接spark集群。感興趣的可以了解一下2021-05-05
python掃描proxy并獲取可用代理ip的實(shí)例
下面小編就為大家?guī)?lái)一篇python掃描proxy并獲取可用代理ip的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08
python中matplotlib調(diào)整圖例位置的方法實(shí)例
在matplotlib中,一般圖例默認(rèn)是在圖表內(nèi)部的,如果要放置到圖例外面,需要對(duì)坐標(biāo)進(jìn)行指定,下面這篇文章主要給大家介紹了關(guān)于python中matplotlib調(diào)整圖例位置的相關(guān)資料,需要的朋友可以參考下2022-06-06
python2和python3在處理字符串上的區(qū)別詳解
這篇文章主要介紹了python2和python3在處理字符串上的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
Python基礎(chǔ)之with語(yǔ)句和上下文管理器詳解
這篇文章主要為大家詳細(xì)介紹了Python中with語(yǔ)句和上下文管理器的具體使用方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-04-04
Python numpy.array()生成相同元素?cái)?shù)組的示例
今天小編就為大家分享一篇Python numpy.array()生成相同元素?cái)?shù)組的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-11-11
Python利用WMI實(shí)現(xiàn)ping命令的例子
今天小編就為大家分享一篇Python利用WMI實(shí)現(xiàn)ping命令的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08

