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

相关推荐
IT北辰19 分钟前
Linux 系统python环境( Miniconda),最新版
linux·运维·python
go_bai20 分钟前
Linux--常见工具
linux·开发语言·经验分享·笔记·vim·学习方法
keerduoba26 分钟前
PDFParser 的pickle.loads 寻找链(源码)wmctf2025-pdf2text
python·pdf·pickle·pdf与pickle反序列化
ajassi200038 分钟前
开源 C# 快速开发(三)复杂控件
开发语言·开源·c#
郝学胜-神的一滴1 小时前
深入理解前端 Axios 框架:特性、使用场景与最佳实践
开发语言·前端·程序人生·软件工程
jf加菲猫1 小时前
条款11:优先选用删除函数,而非private未定义函数
开发语言·c++
歪歪1001 小时前
什么是TCP/UDP/HTTP?
开发语言·网络·网络协议·tcp/ip·http·udp
该用户已不存在1 小时前
PHP、Python、Node.js,谁能称霸2025?
python·node.js·php
luckys.one1 小时前
第12篇|[特殊字符] Freqtrade 交易所接入全解:API、WebSocket、限频配置详解
网络·ide·python·websocket·网络协议·flask·流量运营
WangMing_X1 小时前
C#上位机软件:2.1 .NET项目解决方案的作用
开发语言·c#