python 生成多维数组的一个坑

python 生成多维数组的一个坑

python 的数组类型为list,而list支持乘法改变其长度,比如:

>>> a = [0]
>>> a
[0]
>>> a = a*3
>>> a
[0, 0, 0]

这样就可动态创建一个N长度数组了。

在实验中需要动态生成一个 N * N 的二维数组,为了简单说明,这里假如N=3,在实验中,使用的方法是:

>>> a = [[0] * 3] * 3
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]

这样看着是正确的,是一个符合要求的二维数组,然而~~

在实验过程中,本想赋值为[[1,2,3],[4,5,6],[7,8,9]]的,但最后都是出现 a=[[7, 8, 9], [7, 8, 9], [7, 8, 9]]这样一个结果,也就是他们的值一样了。

但在跟踪时候,只是知道数据不正确,没有留意到他们值是一模一样的细节。之后,各种打日志查看数据变化,才发现只要a[0][0] 被改变了, a[1][0]、a[2][0] 也会跟着变化,顿时想到了问题所在——浅拷贝。

我们把 a = [[0] * 3] * 3 分成几个语句:

>>> x=[0]
>>> x = x * 3   ----------(1)
>>> x
[0, 0, 0]
>>> y = [x] * 3 ----------(2)
>>> y
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]

(1)的位置x 内是个0,基本数据类型,*3 操作后 扩容正常;而(2)x 是个list 对象,这里3 操作操作看似是扩容了,但是只是把 x 的对象的引入拷贝了3份,并不会创建新的对象,也就是说,这里只是个浅拷贝。

可以用id来验证下:

>>> a = [[0] * 3] * 3
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> id(a[0])
4339478600
>>> id(a[1])
4339478600
>>> id(a[2])
4339478600
>>> a[0][1] = 1
>>> a
[[0, 1, 0], [0, 1, 0], [0, 1, 0]]

可以看到a[0]、a[1]和a[2] 这三id 都是4339478600,也就是他们是同一个list对象,只要一个改变了,其他也会跟着变了。

创建二维数组的办法,要么直接使用a=[[0, 0, 0], [0, 0, 0], [0, 0, 0]],但这样不方便动态创建,所以要么将就这样创建了:a=[[0 for i in range(N)] for j in range(N)]。

(全文完)

(欢迎转载本站文章,但请注明作者和出处 云域 – Yuccn

One thought on “python 生成多维数组的一个坑

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注