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)。

相关推荐
程序猿乐锅9 小时前
万字详解Single-flight(单飞模式)
java·开发语言·分布式·后端·学习·single-flight
最强小杰10 小时前
DeepSeek V4 Flash + Codex CLI 接入教程:原生 Responses API 适配,从配置到跑通收藏这篇就够了(2026)
java·前端·python·ai
DeepVisionary10 小时前
为拿并网许可,OpenAI在佐治亚新园区同意高峰期断电三成
python·自动化
揽星河..10 小时前
【C语言】指针
c语言·开发语言
小小数媒成员11 小时前
UGUI原理(一)
开发语言·游戏·unity·游戏引擎
VIP_CQCRE11 小时前
内容自动化越跑越乱?先补上状态、去重和失败恢复
python·ai·工作流·幂等设计·内容自动化
速易达网络11 小时前
Three.js 动画入门教学:从场景搭建到流畅动效
开发语言·javascript·ecmascript
福大大架构师每日一题11 小时前
excelize v2.11.1发布:Go 1.26.0起步,16项安全修复与嵌入对象能力全面升级
开发语言·安全·golang
我喜欢就喜欢11 小时前
RAG 重排序 Rerank 实战:用 bge-reranker 把 Top-K 命中率拉回来
python·大模型·向量检索·rag·rerank