python中關於物件複製有三種型別的使用方式,賦值、淺拷貝與深拷貝。他們既有區別又有聯絡,剛好最近碰到這一類的問題,研究下。
一、賦值
在python中,物件的賦值就是簡單的物件引用,這點和c++不同。如下:
[python]view plain
copy
print?
a = [1,2,3,「hello」,[「python」,「c++」]]
b = a
print a==b #true
a = [1,2,3,"hello",["python","c++"]]
b = a
print a==b #true
這種情況下,b和a是一樣的,他們指向同一片記憶體,b不過是a的別名,是引用。我們可以使用a與b是否相同來判斷,返回true,表明他們位址相同,內容相同。
賦值操作(包括物件作為引數、返回值)不會開闢新的記憶體空間,它只是複製了新物件的引用。也就是說,除了b這個名字以外,沒有其它的記憶體開銷。
修改了a,就影響了b;同理,修改了b就影響了a。
[python]view plain
copy
print?
a = [1,2,3,「hello」,[「python」,「c++」]]
b = a
「a=」,a,「b=」,b
a = [1,2,3,"hello",["python","c++"]]
b = a
print "a=",a,"b=",b
[python]view plain
copy
print?
#a=[1, 2, 3, 『hello』, [『python』, 『c++』], 『add』] b=[1, 2, 3, 『hello』, [『python』, 『c++』], 『add』]
#a=[1, 2, 3, 'hello', ['python', 'c++'], 'add'] b=[1, 2, 3, 'hello', ['python', 'c++'], 'add']
二、淺拷貝(shallow copy)
淺拷貝會建立新物件,其內容是原物件的引用。
淺拷貝有三種形式:切片操作,工廠函式,copy模組中的copy函式。比如對上述a:
1、切片操作:b = a[:] 或者 b = [each for each in a]
2、工廠函式:b = list(a)
3、copy函式:b = copy.copy(a)
淺拷貝產生的b不再是a了,使用is可以發現他們不是同乙個物件,使用id檢視,發現它們也不指向同一片記憶體。但是當我們使用 id(x) for x in a 和 id(x) for x in b 時,可以看到二者包含的元素的位址是相同的。
[python]view plain
copy
print?
a = [1,2,3,「hello」,[「python」,「c++」]]
b = a[:]
「a」,a,「b」,b
a = [1,2,3,"hello",["python","c++"]]
b = a[:]
print "a",a,"b",b
#a [1, 2, 3, 『hello』, [『python』, 『c++』]] b [1, 2, 3, 『hello』, [『python』, 『c++』], 『add』]
但是要注意,淺拷貝之所以稱為淺拷貝,是它僅僅只拷貝了一層,在a中有乙個巢狀的list,如果我們修改了它,情況就不一樣了。
三、深拷貝(deep copy)
深拷貝只有一種形式,copy模組中的deepcopy函式。
和淺拷貝對應,深拷貝拷貝了物件的所有元素,包括多層巢狀的元素。因而,它的時間和空間開銷要高。
同樣對la,若使用b = copy.deepcopy(a),再修改b將不會影響到a了。即使巢狀的列表具有更深的層次,也不會產生任何影響,因為深拷貝出來的物件根本就是乙個全新的物件,不再與原來的物件有任何關聯。
四、關於拷貝操作的警告
1、對於非容器型別,如數字,字元,以及其它「原子」型別,沒有拷貝一說。產生的都是原物件的引用。
2、如果元組變數值包含原子型別物件,即使採用了深拷貝,也只能得到淺拷貝。
python List賦值操作
筆者在近期寫 時遇到乙個有趣的問題,就是關於list賦值的事情。比如a 1,2,3,4 假如把a賦值給b,即b a,如果接下來我們對b進行b b操作,然後輸出a,會發生什麼事情呢?我們可以看到如下的結果,也就是對b的操作也影響到a了。a 1,2,3,4 b a b b print a 1,2,3,4...
python list常用方法
空列表 li 用逗號分割,裡面可以新增任意型別元素 li 1,2,aaa 4,5,6,7 li 1,2,3,4,5 for i in li print i,end t 1 2 3 4 5 索引值可以為負數,代表倒數第幾個元素 li 1,2,3,4,5 print li 2 4for i in ran...
Python list常用方法
除前面章節介紹的增加元素 刪除元素 修改元素方法之外,列表還包含了一些常用的方法。例如,在互動式直譯器中輸入 dir list 即可看到列表包含的所有方法,如下所示 dir list 在上面輸出結果中己經剔除了那些以雙下畫線開頭的方法。按照約定,這些方法都具有特殊的意義,不希望被使用者直接呼叫。上面...