Python3中的指針你了解嗎
技術(shù)背景
在python中定義一個列表時,我們一定要注意其中的可變對象的原理。雖然python的語法中沒有指針,但是實際上定義一個列表變量時,是把變量名指到了一個可變對象上。如果此時我們定義另外一個變量也指到同一個可變對象的話,就會造成一個“聯(lián)動”的現(xiàn)象。也就是改變其中的一個值時,另一個值也會隨之而改變。本文使用的Python版本為Python 3.7.13
測試案例
這里我們先定義一個列表a,然后把這個空的列表a直接賦值給變量b,此時a和b都是一個空的列表:
In [1]: a = [] In [2]: b = a In [3]: print (a,b) [] []
那么如果此時我們修改a的值,那么此前被a賦值的變量b是否也會隨之改變呢?
In [4]: a.append(1) In [5]: print (a,b) [1] [1] In [6]: a.append(2) In [7]: print (a,b) [1, 2] [1, 2] In [8]: a = [3] In [9]: print (a,b) [3] [1, 2] In [10]: a.append(4) In [11]: print (a,b) [3, 4] [1, 2]
從運行結(jié)果來看,我們可以發(fā)現(xiàn),當(dāng)對a先后擴(kuò)展一個元素1和2時,變量b的值也隨之改變,跟a是同步變化的。但是如果把a這個變量名指向一個新的列表上,此時b的值不會發(fā)生變化。這就相當(dāng)于,給變量a賦新的值的時候,變量b指向了a原來的值,而a這個變量名指向了新的數(shù)值,此后兩者之間的關(guān)聯(lián)就消失了。之所以沒有指針定義的python編程語言,會出現(xiàn)這樣的情況,就是因為列表類型屬于可變參量,所以如果把兩個變量指向同一個列表,兩個變量的值是會同步的,即使初始的列表不是一個空的列表,結(jié)果也是一樣的:
In [23]: a = [1] In [24]: b = a In [25]: a += [2] In [26]: print (a,b) [1, 2] [1, 2]
而且這個同步還是雙向的,也就是說,修改a會同步到b,修改b也會同步到a:
In [11]: a = [] In [12]: b = a In [13]: b.append(5) In [14]: print (a,b) [5] [5]
那么除了列表這個數(shù)據(jù)結(jié)構(gòu)之外,其他類型的數(shù)據(jù)結(jié)構(gòu)是否存在類似的現(xiàn)象呢?首先用字典類型來測試一下:
In [10]: a = {} In [11]: b = a In [12]: print (a,b) {} {} In [13]: a[1]=1 In [14]: print (a,b) {1: 1} {1: 1}
經(jīng)過測試我們發(fā)現(xiàn),字典也是屬于可變參量的類型。除了列表和字典外,其他的就是普通的數(shù)值類型和元組Tuple類型,還有一些第三方定義的數(shù)據(jù)類型,也可以分別測試一下:
In [15]: a = 1 In [16]: b = a In [17]: a += 1 In [18]: print (a,b) 2 1 In [19]: a = (1,) In [20]: b = a In [21]: a += (2,) In [22]: print (a,b) (1, 2) (1,) In [23]: a = '1' In [24]: b = a In [25]: a += '2' In [26]: print (a,b) 12 1
測試結(jié)果表明,數(shù)值類型和元組類型在“鏈?zhǔn)?rdquo;賦值之后,是直接把值給了其他變量的,而不是傳遞一個指針。但是另一個需要引起重視的是,第三方numpy所定義的array,也是一個可變參量:
In [15]: a = 1 In [16]: b = a In [17]: a += 1 In [18]: print (a,b) 2 1 In [19]: a = (1,) In [20]: b = a In [21]: a += (2,) In [22]: print (a,b) (1, 2) (1,) In [23]: a = '1' In [24]: b = a In [25]: a += '2' In [26]: print (a,b) 12 1
可以發(fā)現(xiàn),a和b兩者的結(jié)果也是同步變化的。因為沒研究過Python的底層實現(xiàn),也許區(qū)分可變參量和非可變參量的方法,就是看其能不能被哈希
?
In [15]: hash(1) Out[15]: 1 In [16]: hash([1]) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-16-0579e98ca3ee> in <module> ----> 1 hash([1]) TypeError: unhashable type: 'list' In [17]: hash({'1':1}) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-17-b18acecf6a20> in <module> ----> 1 hash({'1':1}) TypeError: unhashable type: 'dict' In [18]: hash((1,)) Out[18]: 3430019387558 In [29]: hash(np.array([1.])) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-29-b9e8d96de6be> in <module> ----> 1 hash(np.array([1.])) TypeError: unhashable type: 'numpy.ndarray' In [30]: hash(np.array([1.]).tobytes()) Out[30]: 1211024724661850177
從結(jié)果中我們發(fā)現(xiàn),那些可以被哈希的類型都是非可變參量,也就是在“鏈?zhǔn)劫x值”的過程中不會發(fā)生“聯(lián)動”的類型。
總結(jié)概要
假如你在Python中初始化了一個變量a的值,然后用a來初始化另一個變量b,此時你希望得到的b的數(shù)值是跟a同步變化的,還是獨立變化的呢?Python這個編程語言雖然沒有指針類型,但是Python中的可變參量也可以像指針一樣,改變一個數(shù)值之后,所有指向該數(shù)值的可變參量都會隨之而改變。就比如說改變a的值,會同步的去改變b的值。那么我們應(yīng)該對這種類型的賦值有所了解,才能夠避免在實際的編程中犯錯。
到此這篇關(guān)于Python3中的指針你了解嗎的文章就介紹到這了,更多相關(guān)Python3 指針內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pytorch 實現(xiàn)在測試的時候啟用dropout
這篇文章主要介紹了pytorch 實現(xiàn)在測試的時候啟用dropout的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-05-05tensorflow2.0實現(xiàn)復(fù)雜神經(jīng)網(wǎng)絡(luò)(多輸入多輸出nn,Resnet)
這篇文章主要介紹了tensorflow2.0實現(xiàn)復(fù)雜神經(jīng)網(wǎng)絡(luò)(多輸入多輸出nn,Resnet),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03Python中表達(dá)式x += y和x = x+y 的區(qū)別詳解
這篇文章主要跟大家介紹了關(guān)于Python中x += y和x = x+y 的區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。2017-06-06PyTorch?模型?onnx?文件導(dǎo)出及調(diào)用詳情
這篇文章主要介紹了PyTorch模型onnx文件導(dǎo)出及調(diào)用詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-07-07