python二维数组初始化的一个极其隐蔽的bug(浅拷贝)

初始化一个三行三列的矩阵

csharp 复制代码
m = n = 3

初始化方式1

csharp 复制代码
a = [[0 for i in range(m)] for j in range(n)]

初始化方式2

csharp 复制代码
b = []
row = [0 for i in range(0,m)]
for i in range(0,n):
    b.append(row)

分别输出两个初始化的结果

csharp 复制代码
for row in a:
    print(row)
for row in b:
    print(row)

当前的输出为:

当我修改0,0位置的数值的时候,奇怪事情发生了,两种初始化方式的不同导致结果的不同:

csharp 复制代码
a[0][0] = 1
b[0][0] = 1

for row in a:
    print(row)
print()
for row in b:
    print(row)

a数组是正常的输出,但是b数组的整列的值都发生了改变,很奇怪。

我再尝试修改其他位置的值,得到类似的结果:

csharp 复制代码
a[0][1] = 1
b[0][1] = 1

for row in a:
    print(row)
print()
for row in b:
    print(row)
csharp 复制代码
a[1][2] = 1
b[1][2] = 1

for row in a:
    print(row)
print()
for row in b:
    print(row)


很奇怪!!!

原因:是因为第一种初始化方式相当于定义了三个一维的列表,三个一维的列表之间不会相互影响。而第二种初始化方式是因为只定义了一个 叫做 row 的一维列表,append的过程中是浅拷贝这个row的过程(浅拷贝只是第一层,三个一维列表都指向了row,一维列表之间并不是相互独立的),所以在修改一维列表的内部的元素的时候,其他的append的row都被修改了(实际上是三行的一维列表都是一个row)。

相关推荐
Esaka_Forever17 小时前
Python 与 JS (V8) 垃圾回收核心区别 + 底层根源分析
开发语言·javascript·jvm
pp起床17 小时前
黑马点评 - 短信验证码登录实现
java·开发语言·tomcat
芒鸽17 小时前
在仓颉语言里造一个没有反射的服务端框架
开发语言·华为·harmonyos
CodeStats17 小时前
《源纹天书》第121-125章:源匠归来——全栈重构与归元圣域的2.0时代
java·开发语言·源纹天书
binbin_5217 小时前
UIAbility 与 WindowStage:窗口创建、加载、销毁的完整链路
开发语言·javascript·深度学习·华为·harmonyos
AI人工智能+电脑小能手17 小时前
【大白话说Java面试题 第154题】【06_Spring篇】第14题:Spring 支持的 Bean 作用域
java·开发语言·spring·面试
程序员杰哥17 小时前
接口自动化测试项目框架详解
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·接口测试
love530love17 小时前
AI Agent + 本地 ComfyUI 无头模式实战:关闭 IDE 后 AI 独立重启并完成图文生成
ide·人工智能·windows·python·音视频·agent·devops
FriendshipT17 小时前
Ultralytics:解读Attention模块
人工智能·pytorch·python·深度学习·目标检测
旖-旎17 小时前
QT界面优化(6)
开发语言·c++·qt