list[] 和 list[:] 的理解
首先,python中沒有賦值的說法,只有名稱到對象的引用;
list2 = list1是把list1所指的對象綁定到名字list2上,沒有產生新list,只是新增了一個引用;
正因為兩個名稱指向的同一個對象,所以修改list1,那么list2也會改變;
通俗理解:以前有一套三室一廳的房子,戶主叫list1。后來list1和list2結婚,房產證上戶主的名字加了一個,但房子還是只有一套。list1如果把客廳刷成了藍色,那list2回家的時候會發現客廳是藍色的了。
而list2 = list1[:]則是把list1通過切片運算取得的新list對象綁定到list2上,產生了新list,名稱和引用也不同,所以,修改其中一個,另一個不會變。
注意,這里的切片是淺拷貝,參考下面的筆記。
淺拷貝會創建新對象,其內容是原對象的引用。
淺拷貝有三種形式:切片操作,工廠函數,copy模塊中的copy函數。
比如對:a = [1,2,3,"hello",["python","C++"]]
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 時,可以看到二者包含的元素的地址是相同的。
在這種情況下,a和b是不同的對象,修改b理論上不會影響a。
比如b.append([4,5]):
b = a[:]
b.append("ADD")
輸出:a [1, 2, 3, 'hello', ['python', 'C++']] b [1, 2, 3, 'hello', ['python', 'C++'], 'ADD']
注:淺拷貝之所以稱為淺拷貝,是它僅僅只拷貝了一層,在a中有一個嵌套的list,如果我們修改了它,情況就不一樣了。
深拷貝(deep copy)
深拷貝只有一種形式,copy模塊中的deepcopy函數。
和淺拷貝對應,深拷貝拷貝了對象的所有元素,包括多層嵌套的元素。因而,它的時間和空間開銷要高。