python3的对象引用、浅拷贝与深拷贝
对象引用
由于python使用了对象引用,因此在使用复制操作符“=”时并没有进行复制。
如果右面的操作数是字面值(字符串、数字等),那么左边的操作数就被设置为一个对象引用,指向存放该值的内存对象;如果右边的操作数是一个对象引用,那么左边的操作数将指向与右面的对象引用相同的内存对象。
>>>songs = ["Because","Boys","Carol"]
>>>beatles = songs
>>>beatles ,songs
(['Because', 'Boys', 'Carol'], ['Because', 'Boys', 'Carol'])
beatles 和songs都指向了同一列表 ["Because","Boys","Carol"]。
>>>beatles[2] = "Cayenme"
>>>beatles ,songs
>>>(['Because', 'Boys', 'Cayenme'], ['Because', 'Boys', 'Cayenme'])
对列表 ["Because","Boys","Carol"]修改之后,这两个指向该列表的对象引用都发生了变化。
浅拷贝
如果需要可变对象(元组、列表等)的一个单独的副本,可以使用切片,切片总是取自数据项的一个单独的副本。
字典和集合可以使用dict.copy()与set.copy()来实现。
另外copy模块提供的copy.copy()函数可以返回指定对象的副本。
对内置数据类型还可以使用类型名称名作为函数,类似于进行类型转换的格式:
copy_of_dict_d = dict(d)
对于数字与字符串,这与复制的效果是一样的,但对于可变的数据类型,比如嵌套的组合类型,这意味着相关对象同时被原来的组合与复制来的组合引用:
>>>x = [53,68,["A","B","C"]
>>>y = x[:] #进行切片
>>>x,y
([53, 68, ['A', 'B', 'C'], [53, 68, ['A', 'B', 'C'])
>>>y[1] = 40
>>>x[2][0]="Q"
>>>x,y
([53, 40, ['Q', 'B', 'C'], [53, 40, ['Q', 'B', 'C'])
深拷贝
上例中,对嵌套的列表的更改对于x、y都是可见的,如果需要一个独立的副本或任意的嵌套组合,可以使用copy模块的copy.deepcopy()进行深拷贝。
>>>import copy
>>>x = [53,68,["A","B","C"]
>>>y = copy.deepcopy(x)
>>>y[1] = 40
>>>x[2][0]="Q"
>>>x,y
([53, 68, ['Q', 'B', 'C'], [53, 40, ['A', 'B', 'C'])
x和y这两个列表及各自所包含的项都是完全独立的了。
由于python使用了对象引用,因此在使用复制操作符“=”时并没有进行复制。
如果右面的操作数是字面值(字符串、数字等),那么左边的操作数就被设置为一个对象引用,指向存放该值的内存对象;如果右边的操作数是一个对象引用,那么左边的操作数将指向与右面的对象引用相同的内存对象。
>>>songs = ["Because","Boys","Carol"]
>>>beatles = songs
>>>beatles ,songs
(['Because', 'Boys', 'Carol'], ['Because', 'Boys', 'Carol'])
beatles 和songs都指向了同一列表 ["Because","Boys","Carol"]。
>>>beatles[2] = "Cayenme"
>>>beatles ,songs
>>>(['Because', 'Boys', 'Cayenme'], ['Because', 'Boys', 'Cayenme'])
对列表 ["Because","Boys","Carol"]修改之后,这两个指向该列表的对象引用都发生了变化。
浅拷贝
如果需要可变对象(元组、列表等)的一个单独的副本,可以使用切片,切片总是取自数据项的一个单独的副本。
字典和集合可以使用dict.copy()与set.copy()来实现。
另外copy模块提供的copy.copy()函数可以返回指定对象的副本。
对内置数据类型还可以使用类型名称名作为函数,类似于进行类型转换的格式:
copy_of_dict_d = dict(d)
对于数字与字符串,这与复制的效果是一样的,但对于可变的数据类型,比如嵌套的组合类型,这意味着相关对象同时被原来的组合与复制来的组合引用:
>>>x = [53,68,["A","B","C"]
>>>y = x[:] #进行切片
>>>x,y
([53, 68, ['A', 'B', 'C'], [53, 68, ['A', 'B', 'C'])
>>>y[1] = 40
>>>x[2][0]="Q"
>>>x,y
([53, 40, ['Q', 'B', 'C'], [53, 40, ['Q', 'B', 'C'])
深拷贝
上例中,对嵌套的列表的更改对于x、y都是可见的,如果需要一个独立的副本或任意的嵌套组合,可以使用copy模块的copy.deepcopy()进行深拷贝。
>>>import copy
>>>x = [53,68,["A","B","C"]
>>>y = copy.deepcopy(x)
>>>y[1] = 40
>>>x[2][0]="Q"
>>>x,y
([53, 68, ['Q', 'B', 'C'], [53, 40, ['A', 'B', 'C'])
x和y这两个列表及各自所包含的项都是完全独立的了。