Python二维数组初始化陷阱:引用与深拷贝的区别
本文详解Python中使用乘法运算符*初始化二维数组时的引用陷阱,指出其仅增加引用而非创建新对象。通过对比列表推导式与Numpy数组乘法,展示正确初始化方法及数值运算效果,帮助开发者避免数据修改时的意外副作用。
注意事项
在Python中,执行 [object] * n 操作时,并不会创建 n-1 个独立的 object 副本,而是生成 n-1 个指向同一个 object 的引用。
例子说明
目标:生成一个 10*10 且所有值都是 0 的二维数组
方法一:
[ [0] * 10] * 10
方法二:
[ [0 for _ in range(10)] for _ in range(10)]
本以为两种方法得到的结果是一样,但是在使用时发现有些不一样。如下面的代码所示。
当仅仅更改 a[2][2] 的值的时候,a[k][2] (k取0到9)全部被更改成了 4。
其实这是因为 [object] * n 的时候并没有复制 n-1 个 object,而是增加了 n-1 个引用。
a = [ [0] * 10] * 10
b = [ [0 for _ in range(10)] for _ in range(10)]
a[2][2] = 4
b[2][2] = 4
for i in a:
print(i)
print("--------")
for i in b:
print(i)
[0, 0, 4, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 4, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 4, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 4, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 4, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 4, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 4, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 4, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 4, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 4, 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, 0, 0]
[0, 0, 4, 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, 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, 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, 0, 0]
补充:python 中 numpy 数组与数组使用*相乘的效果
输入:
import numpy as np
b = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
a = np.array([150,270,150,270])
b2 = b * a
print(b)
print(a)
print(b2)
输出:
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[150 270 150 270]
[[ 150 540 450 1080]
[ 750 1620 1050 2160]
[1350 2700 1650 3240]]
以上为个人经验,希望能给大家一个参考,也希望大家多多支持本站。如有错误或未考虑完全的地方,望不吝赐教。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









