1. 程式人生 > >關於Python中的可變物件與不可變物件的區別

關於Python中的可變物件與不可變物件的區別

Python中的可變物件與不可變物件

什麼是可變物件/不可變物件:

可變物件:物件存放在地址中的值不會被改變(所謂的改變是建立了一塊新的地址並把新的物件的值放在新地址中原來的物件並沒有發生變化)

不可變物件:物件存放在地址中的值會原地改變

int str float tuple 都屬於不可變物件 其中tuple有些特殊(下文解釋) 

dict set list 屬於可變物件

不可變物件例項:

性質1:

首先,看一下int型別:

a=1
b=1
c=a+0
print(a is b)
print(a is c)

is是對兩個變數的id是否相等做出判斷如果相等那麼返回true 否則返回false

可以發現上述程式碼最終結果是列印了兩個true

這裡float str型別不再一一列出如果有興趣可以自己除錯一下發現 此類不可變變數有這樣一個性質:

在除了tuple的不可變變數中,只要兩個變數的資料型別相同並且值也相等,那麼這兩個變數的地址也相同

tuple是不符合這一性質的

a=(1,2,3)
b=(1,2,3)
print(a is b)

返回false 

這就是tuple相對於其他不可變變數的特殊性

上述不可變變數性質的優點在於減少了重複的值對記憶體空間的佔用

性質2:

變數的不可變具體不可變在哪?

來看下面的程式碼:

i=73
print(id(i))
i+=2
print(id(i))

可以看出上面程式碼的執行結果a的值發生變化後地址也變了,工作原理如下圖所示:

需要注意的是i是一個變數,它指向物件的內容是73,當執行i+=2時,首先創建出一個新的記憶體裡面存放改變後的值(75),然後讓i指向新的地址,這是不可變物件在“改變”時的執行步驟,原來的物件內容和記憶體並沒有發生變化

我們再來看一下字串:

a="abc"
print(a.replace("a","A"))
print(a)

a執行replace 後把裡面的“a”換成了“A“相當於建立的新的地址存放”Abc“ ,但是並沒有再讓a指向這塊新的地址所以a並沒有變化,通過這一性質我們可以推出:對於不變物件來說,呼叫物件自身的任意方法,也不會改變該物件自身的內容。相反,這些方法會建立新的物件並返回,這樣,就保證了不可變物件本身永遠是不可變的。

可變物件例項:

關於可變物件,是不滿足上述的不可變物件性質一的而性質二剛好相反

可變物件對於自身的任意方法,是不需要重新開闢記憶體空間的,而是原地改變:

m=[5,9]
m.append(6)
print(m)

m的值變為了[5,9,6]當執行append時由於m是list型別屬於可變物件所以它不會開闢新的記憶體空間而是像下圖一樣原地改變其值:

注意:

當list用“+”來運算時會開闢新的記憶體空間

a1 = [1, 2, 3]
a2 = a1
print(id(a1), id(a2))
# 實際上是a2指向了新的物件,id已經改變。
# 所以現在a2、a1並不是同一物件的兩個引用了,a2變化a1不會改變
a2 = a2 + [4] # 這個等式中,右邊的a2還是和a1的id一樣的,一旦賦值成功,a2就指向新的物件
print(id(1), id(a2))  # 不等,a2的id變化了
print(a1) # [1, 2, 3]沒有變

如果是這樣寫:

a1 = [1, 2, 3]
a2 = a1
print(id(a1), id(a2))
a2 += [4]  # 相當於呼叫了a2.extend([4]),原地改變並沒有新的物件產生
print(id(1), id(a2))  # 相等,a2的id沒有變化
print(a1) 

不同的地方在於a2 += [4],這句相當於呼叫了a2.extend([4])相當於原地改變,並沒有新的物件產生。


相關推薦

Python可變物件可變物件

什麼是可變/不可變物件 不可變物件,該物件所指向的記憶體中的值不能被改變。當改變某個變數時候,由於其所指的值不能被改變,相當於把原來的值複製一份後再改變,這會開闢一個新的地址,變數再指向這個新的地址。 可變物件,該物件所指向的記憶體中的值可以被改變。變數(準確的說是引

關於Python可變物件可變物件區別

Python中的可變物件與不可變物件什麼是可變物件/不可變物件:可變物件:物件存放在地址中的值不會被改變(所謂的改變是建立了一塊新的地址並把新的物件的值放在新地址中原來的物件並沒有發生變化)不可變物件:物件存放在地址中的值會原地改變int str float tuple 都屬

python筆記-可變物件可變物件

        python中,萬物皆物件。所有的物件可以分為可變物件與不可變物件兩類。當變數引用不可變物件時,使用該變數的任何操作,都會建立新物件,而不會改變引用的物件。與此相反,變數引用可變物件時,或者可能建立新的物件,或者改變被引用的物件本身,這取決於進

java可變物件可變物件

可變物件(mutable Objects),不可變物件(Immutable ojbects),那麼他們有什麼區別呢? 不可變物件意味著這個物件是final的,物件中所有的公共屬性是final的。同時說明這個物件是執行緒安全的,這意味著他們可以在多執行緒中使用,而不需要使用s

可變物件可變物件

  在之前的一篇文章“python中的賦值 值傳遞?”中,因為在呼叫方法時與方法內部,輸出id是相同,所以不能理解官方的那句話 Remember that arguments are passed by assignment in Python.  要記住,Pyth

Java 可變物件可變物件

可變物件與不可變物件 概念1 不可變物件(Immutable Objects)即物件一旦被建立它的狀態(物件的資料,也即物件屬性值)就不能改變,任何對它的改變都應該產生一個新的物件 String str = "a" ; str = "b" ; // 兩

Python可變型別可變型別資料在記憶體的引用

在Python中主要有兩種資料型別, 一種是可變資料型別, 另一種是不可變資料型別 不可變資料型別 數字型: int, float, complex, bool, long 字元型: str 元 祖: tuple 可變資料型別 列表:

關於可變物件可變物件,變數

上面我們講了,str是不變物件,而list是可變物件。對於可變物件,比如list,對list進行操作,list內部的內容是會變化的,比如:>>> a = ['c', 'b', 'a'] >>> a.sort() >>> a

python 可變變數可變變數區分

轉:https://blog.csdn.net/god_wen/article/details/78423621 不可變變數 我們可以通過下面的例子來感受上面的話   <span style="color:#000000"><code>5245405

一步步學spark之一scala函式程式設計序列,可變列表可變列表3.2

一步步學spark之一scala函式程式設計中序列,可變列表與不可變列表 定義List集合 head就是去列表中第一個元素 tail就是除了第一個元素以外的其他元素列表 另一種定義list方法 把新的數加入到list中

python基礎】可變型別可變型別

從上面的文章可以總結出Python中變數名和物件是分離的,通過“=”給變數賦值時,實際上引用變數指向一個物件,而這個物件則是對應記憶體中儲存的一塊資料,取消引用時,Python會回收記憶體。 In [1]: a=100 這個語句執行的意思是:設定記憶體中一塊區域儲存

scala可變var可變val的理解

我們定義變數的時候分為var可變變數和val不可變變數。 我們使用容器的時候也分為可變容器和不可變容器。 List和Tuple本身就是不可變的,set和map分為可變和不可變的,預設為不可變。 我們看這樣一個例子

Scala可變陣列可變陣列的區別可變集合可變集合的區別、ArrayArrayBuffer的區別、ListListBuffer的區別

不可變陣列與可變陣列的區別 Array與ArrayBuffer的區別 Array為不可變陣列,ArrayBuffer為可變陣列,兩則的區別比較好理解: 不可變指的是長度不可變。Array不能新增或刪除元素,沒有+=和-=方法;而ArrayBuffer可以新增或刪除元素。 注意點:Ar

Scala 可變陣列可變陣列

(*)陣列 java中的集合都是可變集合 在scala中集合分為可變集合和不可變集合 不可變陣列預設可以使用 長度不可以改變,內容可以改變 可變陣列必須引用:import scala.collection.mutable.ArrayBuffer

可變序列可變序列

直接 空間 引用 bsp 不可 nbsp 無法 可變 一個 可變類型: 比如列表:列表名(或稱為列表引用)指向堆空間中的一個列表。列表引用當中存儲的內容為地址,可以指向堆內存中的具體對象. 一方面,該列表可以保證在地址不

可變可變類的區別

 所謂不可變類,是指當建立了這個類的例項後,就不允許修改它的屬性值。在JDK的基本類庫中,所有基本型別的包裝類,如Integer和Long類,都是不可變類,java.lang.String也是不可變類。以下程式碼建立了一個String物件和Integer物件,它們的值分別為“

OC學習----可變陣列可變陣列

NSArray / NSMutableArray 在OC中,我們用 NSArray 類和 NSMutableArray 類來表示陣列.其中, NSArray 類是 NSMutableArray 類的父類.在OC中,我們的陣列是有序的 物件 的集合,即我們的陣列

可變型別可變型別總結

1、不可變型別:是直接把值賦給一個變數(a=1),引用(記憶體中的地址)是一直不變的,除了重新給a賦值才會改變引用。 2、可變型別: (1)可變型別的資料變化,是通過方法來實現的(不會改變地址) (2)如果給一個可變型別的變數,賦值了一個新的資料,引用會修改(會改變地址)

$Django 路飛之redis記憶體資料庫安裝,python使用,Memcached,mongodb的區別

一 redis記憶體資料庫安裝   1.官網下載   2.啟動服務端       redis-server 命令啟動redis服務。         啟動redis服務還有個更方便的方法是把redis加入到Windows服務。         使用cmd進到redis目

python [0]*20*2的區別

程式用例: a=[[1,2],[4,5]] b=[0]*len(a) d=0*len(a) print("len(a)=",len(a)) print("b=",b) print("d=",d) print(2*[1,2]) print([1,2]*2) 輸出如下: len(a)= 2 b=