Python中复制数据有四种方式: 直接赋值、复制、切片、推导式
直接赋值:其实就是对象的引用(别名),a和b都指向同一个对象。
这是因为python关于变量方面的处理和C语言有很大不同
C语言中定义一个变量是先声明数据类型,再定义一个变量,并根据数据类型分配一个地址。而python采用的是基于值的内存管理方式,python中的变量可当作C语言指针来理解,变量被赋值后会指向数据所在的内存地址。例如:
a=[1,2]
b=a
b.append(3)
本代码中,a,b都指向同一个内存地址,id(a)==id(b)==2077497724224,都指向同一个列表数据,因此,通过b添加一个元素后,a的值也改变了
先说两种数据
不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)
浅拷贝(copy):拷贝父对象,不拷贝对象的内部的子对象。a和b是一个独立的对象,但他们的子对象指向统一对象(是引用)
深拷贝(deepcopy):copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的
这是专业术语的解释,看不懂没关系,只需要知道,对于可变数据类型,执行赋值语句b=a后,若b的值改变,a的值也会变,对于浅拷贝,子对象如果也是可变数据类型,那么子对象改变另一方也会改变,比如拷贝一个列表a=[[1]],b=a.copy(),如果这个时候a[0].append(1),那么b[0]也会随之改变,但如果直接a.append(1),此时b不改变,这就是拷贝父对象,引用子对象的含义。而深度拷贝则不同,下例,
import copy
a=[]
b=copy.deepcopy(a)
此时a和b成为各自独立的两个变量,改变a或b的值不会改变另一个变量的值。
另外,对于支持索引的数据类型(列表,元组,字典,字符串),还可以通过切片的方式完成拷贝,如果数组元素是不可变数据,那就相当于深拷贝,如果数组元素是可变数据,那就相当于浅拷贝,下例,
a=[]
b=a[:] 或 b=[::] # a,b能否独立取决于a的元素是否为不可变数据
列表切片格式: [start : end : step]
start:起始索引,默认从0开始,-1表示从右数第一个
end:结束索引,且不包括该索引,类似于range的末位取值
step:步长,步长为正时,从左向右取值;步长为负时,从右往左取值
列表集合字典推导式,别人都讲很清楚了,我这里只提两点,一是推导式比通过循环来获取列表集合字典要快很多,二是内置方法copy又比推导式快得多