在python程式中,列表list的存貯方式與int的存貯方式是不同的,換句話說,python中可變型別的儲存方式與不可變型別的儲存方式是不同的。
例如,對於單一的元素,有如下操作時:
a =
1b = a
b =5
print
(a, b)
print(id
(a),
id(b)
)# 列印兩個變數的位址
輸出》 1 5
>> 140731421349024 140731421348896
即對整型變數的賦值相當於乙個真正的複製過程,兩個變數有了兩個不同的記憶體位址,其實是因為第3句把第二句覆蓋掉了。
而對列表元素進行賦值時:
a =[[
0,1,
2],2
,3]b = ab[0
]=100print
(a, b)
print(id
(a),
id(b)
)# 列印兩個變數的位址
輸出》 [100, 2, 3] [100, 2, 3]
>> 2847777749608 2847777749608
也就是說列表的賦值本質上是名稱多了乙個,換句話說,就是列表的名字多了乙個,列表還是原來那個列表。兩個變數具有相同的記憶體位址。
下面看一下.copy()方法:
a =[1
,2,3
]b = a.copy()b[
0]=100
print
(a, b)
print(id
(a),
id(b)
)# 列印兩個變數的位址
輸出:>> [1, 2, 3] [100, 2, 3]
>> 2744646268360 2744646268744
看起來問題得到了解決,兩個變數記憶體位址也不一樣了,然而.cpoy()都叫它淺拷貝,原因在於如下所示:
a =[[
0,1,
2],2
,3]b = a.copy()b[
0][1
]=100print
(a, b)
print(id
(a),
id(b)
)# 列印兩個變數的位址
print(id
(a[0])
,id(b[0])
)# 列印兩個變數中變數的位址
輸出:>> [[[0, 100, 2], 2, 3] [[0, 100, 2], 2, 3]
>> 2649294660232 2649295880648
>> 2649294660168 2649294660168
可以看到,.copy()方法只是將第一層列表的元素完全拷貝了乙份新的記憶體,再多一層的列表就沒有拷貝了,因此稱它為淺拷貝。
當列表只有一維時,是可以使用淺拷貝的。
深拷貝:
import copy
a =[[0
,1,2
],2,
3]b = copy.deepcopy(a)b[0
][1]
=100
print
(a, b)
print(id
(a),
id(b)
)# 列印兩個變數的位址
print(id
(a[0])
,id(b[0])
)# 列印兩個變數中變數的位址
輸出:>> [[0, 1, 2], 2, 3] [[0, 100, 2], 2, 3]
>> 2521760495496 2521760589768
>> 2521760495112 2521760547336
深拷貝完全實現了我們想要的拷貝賦值。
類似於list有上述特點的還有集合set 、字典dict,即可變元素,因為只有可變元素在賦值後修改之後才可能出現上述問題,不可變元素要不整個元素修改,要不然不改變,不存在上述問題。
賦值語句的本質是為變數多起乙個名字,即多乙個記憶體指標,【最大的用處在於變數有了新名字原來的名字就可以刪除了】。
類似於賦值語句出現的問題還可能出現在函式傳參過程中,把原列表當作函式引數傳入函式時,如果函式中列表發生修改,原列表也會跟著修改。
python學習 可變list的基本操作
出自 list2 1,2,3,4 list3 one 2,true,3.14 list4 abc list1,list2 list裡面的元素可以是同種元素 也可以是不同種元素 還可以是另乙個list list a b c d list 1 b list 1 g list 1 g del list 1...
Python定義可變引數與list切片
一 如果想讓乙個函式能接受任意個引數,我們就可以定義乙個可變引數 def fn args print args python直譯器會把傳入的一組引數組裝成乙個tuple傳遞給可變引數,因此,在函式內部,直接把變數 args看成乙個 tuple 就好了。二 list切片 取前n個元素,也就是索引為0 ...
Python從list刪除元素
paul同學剛來幾天又要轉走了,那麼我們怎麼把paul 從現有的list中刪除呢?如果paul同學排在最後乙個,我們可以用list的pop 方法刪除 l adam lisa bart paul l.pop paul print l adam lisa bart pop 方法總是刪掉list的最後乙個...