Shallow & Deep Copy in Python3
Contents
记一次python上关于List深浅拷贝的试错。
00 起因
最近刷题时,发现python中关于list深浅拷贝有一种奇怪的矛盾。导致调试一道题的时候绕了老大一圈,下面记录一下。
01 经过
环境:Python3.7.5
众所周知,python在初始化list的时候有很多种写法,其中有一种是
|
|
这句代码是创建list类型、长度为length的数组L
并将其初始化为全0
这是一种非常棒的方法,但是有时候为了省事,会有另外一种写法
|
|
这种方法可以说是非常的python了,好用而且关键是敲的字母少啊
但是刷题往往会遇到二维数组,凭借着我多年python经验,不假思索写出了
|
|
喏,这不就创建了 length2 * length1 的二维数组了么
但是当给第一个数字,也就是DL[0][0]
赋值的时候,会发现神奇的现象
|
|
嗯?怎么回事,我明明只初始化了DL[0][0]
啊,怎么DL[1][0]
、DL[2][0]
全变成1了
突然间回想起了大学时老师上课讲的C++数组深浅拷贝的问题,数组内存分配在堆上,引用是在栈中。深拷贝开辟新的堆空间,再进行值拷贝;浅拷贝只是对原内存的引用进行了拷贝。
python底层实现依然是C/C++,大概率也是这种情况吧。[0] * 3
是对象的重复,开辟了3个int的空间,返回的只是对[0, 0, 0]
的引用;而[[0] * 3] * 3]
是对引用的重复,返回了3个对[0, 0, 0]
的引用,而且3个引用指向同一个内存地址。因此DL[0][0]
、DL[1][0]
、DL[2][0]
指向同一个int内存,对DL[0][0]
的赋值,会导致DL[1][0]
和DL[2][0]
的改变。
02 总结
创建数组、初始化数组的正确姿势:
|
|