今天同學們自建的一個python學習群發來一個問題,他想創建一個二維串列并且做如下賦值,代碼如下:
a = [['']*3] * 3
for m in range(1, 4):
for n in range(1, 4):
a[m-1][n-1] = str(m * n)
print('a[' + str(m-1) + '][' + str(n-1) + '] = ' + a[m-1][n-1], end=' ')
print()
print(type(a))
print(a)
-----------------------------------------------------------------------------------
預想的結果這個二維列串列應該是[[‘1’,‘2’,‘3’],[‘2’,‘4’,‘6’],[‘3’,‘6’,‘9’]]
然而運行結果如下
a[0][0] = 1 a[0][1] = 2 a[0][2] = 3
a[1][0] = 2 a[1][1] = 4 a[1][2] = 6
a[2][0] = 3 a[2][1] = 6 a[2][2] = 9
<class 'list'>
[['3', '6', '9'], ['3', '6', '9'], ['3', '6', '9']]
于是我在賦值陳述句設定斷點,看看各個變數的變化情況,發現每次賦值,對應同一列的元素都會發生改變,

于是我上網查了查“python如何創建二維串列“,得知原來是深淺copy的原因,
淺copy:copy后的變數外殼的記憶體地址不同,但是變數內部元素的記憶體地址相同
舉例:
lst1 = [1, 2, [3, 4]]
lst2 = lst1.copy()
# 對串列進行添加操作
lst1.append(5)
print('-----------第一處對比-----------')
print(lst1)
print(lst2) # 從結果可以看到,lst1改變而lst2沒有改變
# 對其中的串列元素進行添加操作
lst1[2].append('變')
print('-----------第二處對比-----------')
print(lst1)
print(lst2) # 從結果可以看到,lst1和lst2都發生了改變
# 查看他們的ID
print('lst1的id:', id(lst1)) # lst1 與 lst2 的記憶體地址是不同的
print('lst1的id:', id(lst2))
print('lst1第0個元素的id:', id(lst1[0])) # 但是其中的元素的地址是相同的
print('lst2第0個元素的id:', id(lst2[0]))
運行結果:

所以,開篇問題代碼中a = [[' ']*3]*3 這條陳述句中的第二個* 就類似于這里的淺copy,這么說可能不太準確,但是其意思就是這樣得出的串列中的三個串列元素指向的記憶體地址是一樣,也就是這三個串列元素實質是同一個串列,只是可以通過不同的索引得到它們,所以這就解釋了為什么每次賦值的時候同一列的元素都會發生改變,
這里提供一個正確的二維串列的創建方式:
a = [[ 0 for i range(3)] for j in range(3)] # 創建一個3x3的所有元素都為0的二維串列
這樣創建的二維串列不會存在淺copy的問題,
深Copy:copy后的變數外殼的記憶體地址不同,內部元素可變資料型別的地址不同,不可變資料型別的地址相同,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/91835.html
標籤:Python
上一篇:列印printservicelookup lookupdefaultprintservice回傳null
下一篇:云短信免費網站分享
