python的二維數組生成問題

背景:

筆者最近在作一個數據統計程序時,須要用到二維數組。爲了一行搞定生成同值二維數組,結果遇到了一些小bug,實驗了下,終於找到了問題並修復。python

前言:

如何簡單快速生成 連續10個k的字符串,很簡單數組

'k'*10
#kkkkkkkkkk

那如何快速生成 連續十個True的數組(列表)呢?別再for .... xxx.append()了,不美觀也多了好幾行代碼。一行搞定便可。app

[True]*10
#[True, True, True, True, True, True, True, True, True, True]

那若是生成 2x3的全是0的二維數組呢?spa

按照上面的套路還不簡單?也是一行搞定(筆者也是這麼想的,結果bug了。嘛,先看下結果吧,確實是想要的)手到擒來嘛。指針

[[0]*3]*2
#[[0, 0, 0], [0, 0, 0]]

其實這樣有bug!其實這樣有bug!其實這樣有bug!code

案例:

用新舊兩種方法生成全是0的2x3數組,修改座標(1,1)的值爲9.對象

l1 = [[0]*3]*2
l2 = [
    [0,0,0],
    [0,0,0],
]
print('l1原',l1)
print('l2原',l2)
l1[1][1] = 9
l2[1][1] = 9
print('l1改',l1)
print('l2改',l2)

#結果:
#l1原 [[0, 0, 0], [0, 0, 0]]
#l2原 [[0, 0, 0], [0, 0, 0]]
#l1改 [[0, 9, 0], [0, 9, 0]]
#l2改 [[0, 0, 0], [0, 9, 0]]

土方法正常的改值了。咱們帥氣的方法(僞)出現bug了。你會發現全部第二列的數值都改爲了9。內存

爲何呢?字符串

這是由於python的機制問題。class

在python裏,int float str都是深拷貝的,即'x'*n,'x'的值會被複製成n份;

可是list,dist和其餘class等,都是淺拷貝的,即僅僅把對象的內存地址拷貝了一份,全部拷貝出來的數據都會共用一組數據。即c裏咱們常說的指針。

[[0]*3]*2

裏的[0]*3確實進行了深拷貝,因而就至關於變成了 [[0 ,0 ,0 ] ]*2。而外層拷貝變成了拷貝list,即淺拷貝,也就是不管拷貝多少行都在使用同一行的數據。

改變1行數據就變成了改變全部行數據。

 

所以,正確的寫法是(固然也是 一行 哦)

l3 = [([0] * 3) for i in range(2)]
print('l3原',l3)
l3[1][1] = 9
print('l3改',l3)

#結果
#l3原 [[0, 0, 0], [0, 0, 0]]
#l3改 [[0, 0, 0], [0, 9, 0]]

是否是帥氣而簡單呢?

網上還有其餘引用其餘庫的方法去處理。但筆者認爲,import最少的庫,最高效率,最少代碼 去完成是最酷的。至少新手看起來 通俗易懂高大上。

相關文章
相關標籤/搜索