面试必备之Python深、浅拷贝。
聊Python的浅拷贝深拷贝问题之前,先举一个例子:现在你有一份家族名字的列表,你家里人想让你们加入Ed家族但是要保证之前的家族名字列表保持不变,你可能会写一个Python程序如下如:
你发现你确实使得家族名字前面都加上了“Ed”,但与此同时你把原始的家族名字列表也给修改了,这是什么问题导致的呢?下面请看。
变量、引用、对象
开场白:在Python中,有一句话:“一切皆为对象,一切皆为对象的引用“,所以 只要记住这句话就很容易清楚python中的引用、浅拷贝和深拷贝了
在Python中使用一个变量时,都没有声明变量的存在和类型,但变量还是可以工作,如输入a = 1,Python为什么知道那代表一个整数呢?这是因为在Python语言中,这些都是以一个非常自然的方式完成,就像下面这样:
变量创建:一个变量名,就像a,当代码第一次给它赋值时创建了它。
变量类型:类型的概念是存在于对象中而不是变量名中,这里也就是代表上面的1。
变量使用:当变量出现在表达式中,它马上会被当前引用的对象所代替,无论这个变量是什么类型。此外,所有变量必须在使用前明确赋值,使用未赋值的变量会发生错误。
总而言之,变量在赋值的时候才创建,它可以引用任何类型的对象,并且必须在引用之前赋值,所以a = 1实际在Python中有三个操作:
创建一个对象代表值1
创建一个变量a
将变量与对象1连接
重点:类型属于对象,而不是变量,a = 1意思说的不是a就是整型,而是1是整形,只是创建好对象1以后,a被引用的对象1代替。
直接复制
直接赋值举例:
可以看出赋值的时候修改b的列表,a的列表跟着一起修改,并且a,b引用的对象地址相同。(id方法的返回值就是对象的内存地址)
原因:
b = a赋值引用,a和b都指向同一个对象。
解析图:
注:上图解析图来之“易佰教程”
浅拷贝
浅拷贝举例:
现在a,b是一个分别指向独立的对象,所以他们的内在地址不一样,但修改b里面的列表,a也会变。
原因:
b = a.copy(): 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(是引用)。
解析图:
注:上图解析图来之“易佰教程”
深拷贝
深拷贝举例:
可以看出a,b的内存地址不一样,并且修改b内部的值,a里面的值不会变。
原因:
a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的。
解析图:
注:上图解析图来之“易佰教程”
总结
现在已经知道了深、浅拷贝的意思,可以修改第一个程序保证家族名字加一个“Ed”并且保持原始的家族列表不变,具体如下:
列表切片保持副本的方法(实际是浅拷贝)
利用深拷贝
更多关于对象、变量引用的关系请阅读《Python学习手册》(Learning python)第6章“动态类型简介”。(强烈推荐阅读,对理解Python程序非常有帮助)
关注“数据管道”,回复“python学习手册”即可获得第四版中文版和第五版英文版书籍。另qq群也会上传。
题外话之电影推荐:《这个男人来之地球》
“我可以给你一句十个字的十诫:别别别别别别别别别别”
“I can give you the ten commandments in ten words:Don't,Don't,Don't,Don't,Don't,Don't,Don't,Don't,Don't,Don't”
长按下方二维码关注我们
不断升华自己的过程中
你我一起进步