我门来看看Java创建二维数组的格式:
type arrayName[ ][ ];
type [ ][ ]arrayName;
比如:
int [ ][ ] arr=new int [5][3];
一个5行3列的整数二维数组就创建了。轻松写意…
创建一个Python二位数组的尴尬也想模仿一下Java,奈何只能:
>>> li[][] = [][]
File "<stdin>", line 1
li[][] = [][]
^
SyntaxError: invalid syntax
抱歉,行不通。
但是可以这样,
>>> li = [[1,2,3], [4,5,6]]
>>> li
[[1, 2, 3], [4, 5, 6]]
这样又太麻烦,我想有没有更好的方法。
你认为的Python二维数组方法一:
>>> rows, cols = (2, 3)
>>> arr = [[0] * cols] * rows
>>> arr
[[0, 0, 0], [0, 0, 0]]
方法二:
>>> arr = [[0 for i in range(cols)] for j in range(rows)]
>>> arr
[[0, 0, 0], [0, 0, 0]]
两种方式都提供与现在相同的输出。
更改一下元素看看
让我们更改方法一和方法二的数组中的元素:
# 方法一
>>> rows, cols = (2, 3)
>>> arr = [[0] * cols] * rows
>>> arr[0][0] = 1
>>> for row in arr:
... print(row)
...
[1, 0, 0]
[1, 0, 0]
奇怪的事情发生了,明明我只改变了arr[0][0]
,我希望的是第一行的第一个元素更改为1,但每行的第一个元素更改为1。
# 方法二
>>> rows, cols = (2, 3)
>>> arr = [[0 for i in range(cols)] for j in range(rows)]
>>> arr[0][0] = 1
>>> for row in arr:
... print(row)
...
[1, 0, 0]
[0, 0, 0]
方法二正是我想要的答案。
什么原因呢?
全怪Python的浅拷贝,如果你还不懂浅拷贝和深拷贝,看看这篇学习Python一年,这次终于弄懂了浅拷贝和深拷贝
。
我这里就简单解释一下:
方法一中,Python不会创建2个list对象,而是仅创建一个list对象,并且数组arr的所有索引都指向同一列表对象(list
),如图所示。
方法二,会创建2个单独的列表对象,如下图:
所以正确的方式就是用方法二,
也就是
rows, cols = (5, 5)
arr2 = [[0 for i in range(cols)] for j in range(rows)]
一个 5行5列的二维数组就创建成功:
>>> for row in arr2:
... print(row)
...
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
不过,还没完,还有一点,我们发现i
和j
好像都没使用,所以我们用单下划线_
:
rows, cols = (5, 5)
arr2 = [[0 for _ in range(cols)] for _ in range(rows)]
总结有时候单个独立下划线是用作一个名字,来表示某个变量是临时的或无关紧要的。
至此,我们终于能够正确创建一个Python的二维数组了。对,就是它:
arr2 = [[0 for _ in range(5)] for _ in range(5)] # 创建一个正确的5行5列的数组