python 用list of lists表示矩陣的問題?
題主刷leetCode的時候發現的一個小情況&>_&< 不知道緣由是什麼,請各位知友幫忙看看~~
python 初始化 a list of lists of integer,就用了如下方式(假設是4 x 4的方陣):n = 4matrix = [[0]*n]*nprint matrix
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]然後詭異的是,假如我只想給第二行的中間兩個元素賦值:matrix[1][1:3] = [1, 2]結果會是:print matrix[[0, 1, 2, 0], [0, 1, 2, 0], [0, 1, 2, 0], [0, 1, 2, 0]]但是如果用如下方式初始化matrix:matrix = [[0 for col in range(n)] for row in range(n)]matrix[1][1:3] = [1, 2]
print matrix[[0, 0, 0, 0], [0, 1, 2, 0], [0, 0, 0, 0], [0, 0, 0, 0]]會是我想要的答案。但是不知道第一種初始化方式錯在哪裡...
matrix = [[0]*n]*n
等價於
fuck = [0]*n
matrix = [fuck]*n
後面你都知道了,matrix的四個數組其實都是fuck,他們都是指向同一個數組實例。你改了一個當然會表現為四個都改了。
贊同樓上,另外要處理矩陣相關的話用 NumPy
#!/usr/bin/python
#encoding=utf-8
# 內容來自python cookbook 第二版 第4.5章節
# 在無須共享引用的條件下創建列表的列表
# 避免隱式的引用共享
multi = [ [0] * 5 ] * 3
print multi
multi[0][0] = "oops"
print multi
# [ [ "oops", 0, 0, 0, 0 ],[ "oops", 0, 0, 0, 0],[ "oops", 0, 0, 0, 0 ] ]
# 等價方式
row = [0] * 5 # row 列表中的5個子項都是引用0
multi = row * 3 # multi 列表中的3個子項都是引用row
# 解釋: 在row創建中, 有無引用被複制完全不重要, 因為被引用的
# 是數字, 而數字不可改變,換句話說,如果對象是不可改變的,則
# 對象和對對象的引用實際沒有區別。
# multi創建中,包含了3個對[row] 內容引用,而其內容則是對一個
# 列表的引用。因此修改時候其他3個引用也改變了,甚至row也改變
# 解決方法:
multilist_method1 = [ [ 0 for col in range(5) ] for row in range(3) ]
multilist_method2 = [ [0] * 5 for row in range(3) ]
multilist_method1[0][0] = "abc"
multilist_method2[0][0] = "edf"
print multilist_method1
print multilist_method2
這個問題,在《Python cookbook》第二版p148頁提到,即隱式的引用共享問題。解決的方案是使用列表推導。詳細你可以看看書。(不好意思手機碼字懶得寫太多了,希望能解決你的問題。)
第一種是淺拷貝
a=[[0]*3]*3
等價於b=[0]*3a=[b]*3
貼一段代碼b=[0]*3
a=[b]*3
print a
a[0][0]=5
print b
print a
看看這段代碼的輸出結果
[[0, 0, 0], [0, 0, 0], [0, 0, 0]][5, 0, 0][[5, 0, 0], [5, 0, 0], [5, 0, 0]]所以a=[b]*3相當於複製三次變數名b(也就是產生了三個別名/引用吧)然後賦予a,改了a中b的別名,相當於改了所有的b。刷leetcode用python坑多啊,昨天剛遇到一個python的除法和餘數機制和c不一樣啊
推薦閱讀:
※python 能否print到console固定一行?
※期權的高頻交易回測平台怎麼編寫?
※有沒有什麼軟體能夠在Win10系統下將電腦重複的工作自動實現?
※python 函數中傳值,傳的是引用還是複製一份傳給另一個函數,會修改調用函數裡面的值嘛?
※Mixin是什麼概念?
TAG:Python |