Python可變資料型別和不可變資料型別是一個基礎且重要的考點。簡單來說:這裡的可變和不可變是指當變數改變的時候,資料的位址是否會改變!
可變資料類型:如果改變了變數的值,相當於是新建了一個物件(即位址會被改變)。
可變資料類型:變數的值發生變化,但是物件的位址不會改變。
不可變資料型別:元組,字串,數值。
可變資料型態:字典,列表,集合。
在講可變資料型別和不可變資料型別之前我們要先講一下引用的概念。 python變數保存的是對象的引用,這個引用指向堆記憶體裡的對象,在堆中分配的對象分為兩類,一類是可變對象,一類是不可變對象。例如:s1="abc"。
其實變數s1 是物件 abc的引用,s1指向了儲存abc的記憶體位址,如果想看s1的位址值,可以使用函數id,id會把位址值轉換成十進位。使用print(id(s1))即可,如下圖所示:
我們以字串舉例,直接上程式碼:
s1="abc" print(id(s1)) s1="xyz" print(id(s1))
輸出:
140712532603136 140712532603168
從輸出結果可見改變字串型變數的值,位址也會隨之改變。
我們接下來看這個實例,也是面試筆試中常出的題目。
#在上面程式碼基礎上,寫如下程式碼:
s2=s1 print(id(s1)) print(id(s2))
輸出:
743316570224 743316570224
可以看到s2=s1 其實是s2 和s1都指向了同一個地址。
我們繼續,改變s2的值。
s2="def" print(id(s1)) print(s1) print(id(s2)) print(s2)
輸出:
879864758384 xyz 879889887984 def
看到這裡,我們就能夠理解為什麼改變了s2 的值並沒有影響s1的值。因為s1 和s2指向了不同的位址,所以s1的值並沒有被改變!
我們以清單舉例:
l = [1, 2, 3] print(id(l)) l.remove(1) # 删除元素 print(id(l)) l.append(4) # 增加元素 print(id(l)) l[1] = '8' # 修改元素 print(id(l))
輸出:
405927907912 405927907912 405927907912 405927907912
可以看到清單進行增刪改操作,清單的位址都沒有變化,只是改變了變數的值,而不會新建一個對象,變數所引用的對象的位址也不會改變。
再看下面這個實例,與前面的字串賦值實例類似。
l1=['a','b','c'] l2=l1 print(id(l1)) print(id(l2)) l2.append('d') print("************") print(id(l1)) print(l1) print(id(l2)) print(l2)
輸出:
838366483528 838366483528 ************ 838366483528 ['a', 'b', 'c', 'd'] 838366483528 ['a', 'b', 'c', 'd']
輸出結果這裡就不再多做解釋了,因為 l1 和l2的位址相同,所以彼此間會產生影響。
有的同學可能要問,如果想讓list 像字串一樣拷貝並產生同值但是不同位址的兩個list,該如何操作呢?其實這個問題的本質是list直接賦值(用= 是直接賦值)和拷貝的區別(拷貝又分為淺拷貝和深拷貝),我會再寫一篇文章來詳細介紹淺拷貝和深拷貝的相關知識點,也請大家持續關注。
這裡先介紹一種比較簡單的方法進行拷貝,使用list()建構函數,程式碼如下:
l3=['x','y','z'] l4=list(l3) print(id(l3)) print(id(l4)) l4.append('a') print(l3) print(l4)
輸出:
831456302152 831480344136 ['x', 'y', 'z'] ['x', 'y', 'z', 'a']
從結果可以看到, l3 和l4的地址不同,所以彼此間不會發生影響。我們也可以透過使用索引,列表生成式,copy()等方式使兩個列表指向不同的列表對象,這裡就不再一一介紹了!
以上是Python 面試高頻問題:可變資料型別與不可變資料型別的區別的詳細內容。更多資訊請關注PHP中文網其他相關文章!