python列表复制函数 python 复制函数

Python对象的拷贝 Python赋值操作或函数参数传递 , 传递的永远是对象引用(即内存地址),而不是对象内容 。在Python中一切皆对象 , 对象又分为可变(mutable)和不可变(immutable)两种类型 。对象拷贝是指在内存中创建新的对象,产生新的内存地址 。当顶层对象和它的子元素对象全都是immutable不可变对象时,不存在被拷贝,因为没有产生新对象 。浅拷贝(Shallow Copy),拷贝顶层对象,但不会拷贝内部的子元素对象 。深拷贝(Deep Copy),递归拷贝顶层对象,以及它内部的子元素对象 。
Python中一切皆对象 , 对象就像一个塑料盒子 ,  里面装的是数据 。对象有不同类型,例如布尔型和整型,类型决定了可以对它进行的操作 。现实生活中的"陶器"会暗含一些信息(例如它可能很重且易碎,注意不要掉到地上) 。
对象的类型还决定了它装着的数据是允许被修改的变量(可变的mutable)还是不可被修改的常量(不可变的immutable) 。你可以把不可变对象想象成一个透明但封闭的盒子:你可以看到里面装的数据 , 但是无法改变它 。类似地,可变对象就像一个开着口的盒子,你不仅可以看到里面的数据 , 还可以拿出来修改它,但你无法改变这个盒子本身 , 即你无法改变对象的类型 。
对象拷贝是指在内存中创建新的对象 , 产生新的内存地址 。
浅拷贝(Shallow Copy),拷贝顶层对象,但不会拷贝内部的子元素对象 。
2.1.1. 顶层是mutable,子元素全是immutable
当顶层对象是mutable可变对象,但是它的子元素对象全都是immutable不可变对象时,如[1, 'world', 2]
① 创建列表对象并赋值给变量a
② 导入copy模块,使用copy.copy()函数浅拷贝a , 并赋值给变量b
③ 修改变量a的子元素a[0] = 3 , 由于整数是不可变对象,所以并不是修改1变为3,而是更改a[0]指向对象3
当顶层对象是 mutable可变对象,但子元素也存在 mutable可变对象 时,如 [1, 2, ['hello','world']]
① 浅拷贝 copy.copy() 只拷贝了顶层对象,没有拷贝子元素对象['hello','world'],即a[2]和b[2]指向同一个列表对象
② 修改a[2][1] = 'china' , 则b[2][1] = 'china'
当顶层对象是immutable不可变对象,同时它的子元素对象也全都是immutable不可变对象时 , 如(1, 2, 3)
变量a与变量b指向的是同一个元组对象,没有拷贝
当顶层对象是immutable不可变对象时,但子元素存在mutable可变对象时 , 如(1, 2, ['hello','world'])
变量a与变量b指向的是相同的元组对象,并且a[2]与b[2]指向同一个列表 , 所以修改a[2][1]会影响b[2][1]
深拷贝(Deep Copy),递归拷贝顶层对象,以及它内部的子元素对象
当顶层对象是mutable可变对象,但是它的子元素对象全都是immutable不可变对象时,如[1, 'world', 2]
变量a与变量b指向不同的列表对象 , 修改a[0]只是将列表a的第一个元素重新指向新对象 , 不会影响b[0]
当顶层对象是mutable可变对象,但子元素也存在mutable可变对象时,如[1, 2, ['hello','world']]
深拷贝既拷贝了顶层对象,又递归拷贝了子元素对象,所以a[2]与b[2]指向了两个不同的列表对象(但是列表对象的子元素初始指定的字符串对象一样) , 修改a[2][1] = 'china'后,它重新指向了新的字符串对象(内存地址为140531581905808),不会影响到b[2][1]
当顶层对象是immutable不可变对象,同时它的子元素对象也全都是immutable不可变对象时,如(1, 2, 3)
变量a与变量b指向的是同一个元组对象,不存在拷贝

推荐阅读