背景
前幾天,有位同學問我如下的問題:
“temp[0][0]
修改後,爲什麼temp[1][0]
、temp[2][0]
也發生了變化?”
“在Python中二維數組是怎樣定義和使用的?”
今天就來談談這個問題。
技術分析
在 C# 語言中有直接定義二維數組的語法,比如int[,] a = new int[3][4]
;或者int[][] a = new int[3][]
。
而 Python 語言中如果想使用二維數組,那麼必須通過list這種結構來實現。
即list中的每個元素是一個list的結構。類似於 C# 中的int[][]
。
我們以創建一個 4×3 的二維數組進行說明:
x = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [0, 0, 0]]
print(x, type(x))
# [[1, 2, 3], [4, 5, 6], [7, 8, 9], [0, 0, 0]] <class 'list'>
for i in x:
print(i, type(i))
# [1, 2, 3] <class 'list'>
# [4, 5, 6] <class 'list'>
# [7, 8, 9] <class 'list'>
# [0, 0, 0] <class 'list'>
x = [[0 for col in range(3)] for row in range(4)]
print(x, type(x))
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
x[0][0] = 1
print(x, type(x))
# [[1, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
x = [[0] * 3 for row in range(4)]
print(x, type(x))
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
x[1][1] = 1
print(x, type(x))
# [[0, 0, 0], [0, 1, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
跟我們預期的結果是一致的,我們再來看上面同學的問題:
x = [[0] * 3] * 4
print(x, type(x))
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
x[0][0] = 1
print(x, type(x))
# [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]] <class 'list'>
下面代碼與上面代碼等價:
a = [0] * 3
x = [a] * 4
print(x, type(x))
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
x[0][0] = 1
print(x, type(x))
# [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]] <class 'list'>
問題復現了,由於list的元素可以是任何對象,因此列表中所保存的是對象的指針。即使保存一個簡單的[1,2,3]
,也要有3個指針和3個整數對象。
在x = [a] * 4
操作中,只是創建4個指向list的指針而已,所以一旦a
改變,x
中4個a
也會隨之改變。所以出現了以上的問題。
總結
使用list創建二維數組會存在以上的混淆,所以在涉及到二維數組的時候,推薦大家使用numpy
中的ndarray
結構呀。這種結構跟 Matlab 中的數組結構幾乎完全一樣。
import numpy as np
x = np.zeros([3, 4])
x[0, 0] = 1
print(x, type(x))
# [[1. 0. 0. 0.]
# [0. 0. 0. 0.]
# [0. 0. 0. 0.]] <class 'numpy.ndarray'>
好了,今天就到這裏吧!希望大家閱讀完之後能夠有所收穫。See You!
當前活動
我是 終身學習者“老馬”,一個長期踐行“結伴式學習”理念的 中年大叔。
我崇尚分享,渴望成長,於2010年創立了“LSGO軟件技術團隊”,並加入了國內著名的開源組織“Datawhale”,也是“Dre@mtech”、“智能機器人研究中心”和“大數據與哲學社會科學實驗室”的一員。
願我們一起學習,一起進步,相互陪伴,共同成長。
後臺回覆「搜搜搜」,隨機獲取電子資源!
歡迎關注,請掃描二維碼: