坑 python新建二維列表的乙個小坑

2021-10-01 20:53:28 字數 2789 閱讀 5390

今天覆寫pie架構的**,寫完覺得沒什麼問題,結果怎麼跑也跑不通。本來決定跑通就回寢睡覺,一路弄到十二點多,終於地毯式的debug終於找到了問題所在。反正現在精神狀態良好,順便水一篇部落格。

我們常常遇到需要初始化乙個空的二維列表來儲存矩陣資料,如鄰接矩陣等二維結構的資料。

那麼一般來說我們常規的操作是這樣的:

nrows = 3

ncols = 4

array =

for i in range(nrows):

for i in range(ncols):

print(array)

# 輸出

'''[[none, none, none, none], [none, none, none, none], [none, none, none, none]]

'''

為了省事你也可以這麼寫:

nrows = 3

ncols = 4

array = [[none for i in range(ncols)] for j in range(nrows)]

print(array)

# 輸出

'''[[none, none, none, none], [none, none, none, none], [none, none, none, none]]

'''

可惜我這個人有強迫症,第二種寫法還是太長了,超到ide那條分割線的右邊了,而我的強迫症迫使我必須把**注釋整齊地寫在緊靠著ide分割線的右側,所以我就想肯定能有更「短」的寫法。

然後我決定這麼寫:

nrows = 3

ncols = 4

array = [[none]*ncols]*nrows

print(array)

# 輸出

'''[[none, none, none, none], [none, none, none, none], [none, none, none, none]]

'''

簡直完美,我的強迫症得到了極大的滿足,我成功把**注釋寫在緊靠著ide分割線的右側了。

為了防止出錯,我還特地驗證了一下:

nrows = 3

ncols = 4

array1 = [[none for i in range(ncols)] for j in range(nrows)]

array2 = [[none]*ncols]*nrows

print(array1==array2)

# 輸出

'''true

'''

然後我就發現我怎麼也跑不通**了,花了近乙個小時地毯式排查,終於發現了問題:

nrows = 3

ncols = 4

array1 = [[none for i in range(ncols)] for j in range(nrows)]

array2 = [[none]*ncols]*nrows

array1[1][1] = 1

array2[1][1] = 1

print("這是array1:\n",array1)

print("這是array2:\n",array2)

# 輸出

'''這是array1:

[[none, none, none, none], [none, 1, none, none], [none, none, none, none]]

這是array2:

[[none, 1, none, none], [none, 1, none, none], [none, 1, none, none]]

'''

如果是用兩重迴圈新建的二維列表(array1),我去更新某個位置的元素時,發現更新很正常。但是如果是用兩個乘號新建的二位列表(array2),我去更新某個位置的元素時,它會把這一列全部更新一遍。

問題出現了總是很容易能解釋清楚,本質上「*ncols」是無傷大雅的,因為只是複製了none。但是「*nrows」複製的是列表,這就有問題了,列表的複製是複製其位址,所以這三行一維列表本質上是指向位址相同的完全相同的三個列表。

所以更新乙個元素等價於同時更新三行同一位置的元素了。

我之前還在想能這麼簡單的寫還寫兩重迴圈不是太蠢了。果然是我太蠢了。

為了省點事情,這麼改寫就沒有問題了:

nrows = 3

ncols = 4

array1 = [[none for i in range(ncols)] for j in range(nrows)]

array2 = [[none]*ncols for i in range(nrows)]

array1[1][1] = 1

array2[1][1] = 1

print("這是array1:\n",array1)

print("這是array2:\n",array2)

# 輸出

'''這是array1:

[[none, none, none, none], [none, 1, none, none], [none, none, none, none]]

這是array2:

[[none, none, none, none], [none, 1, none, none], [none, none, none, none]]

'''

總之兩個教訓

發現問題時,先反思是不是自己有問題。

強迫症是真的害人。

分享學習共同進步

python二維列表

class vector2 向量 def init self,x 0,y 0 self.x x self.y y 將函式轉移到類中,就是靜態方法 staticmethod 向右取值 defright return vector2 0,1 向上取值 staticmethod defup return ...

Python 列表 二維列表轉換為一維列表

將以下二維列表變為一維列表。nums 1,2,3 4,5,6 7,8,9 num for hang in nums for num in hang 1,2,3,4,5,6,7,8,9 res for hang in nums for num in hang 1,2,3,4,5,6,7,8,9 res...

python二維列表排序

假設有乙個學生列表儲存了學號,姓名,年齡資訊 students 3,jack 12 2,rose 13 1,tom 10 5,sam 12 4,joy 8 按學號順序排序 sorted students,key lambda x x 0 1,tom 10 2,rose 13 3,jack 12 4,...