在python中经常要对list进行复制,深拷贝和浅拷贝的区别在于,从原本的list中复制出来的新的new_list,修改其中任何一个是否会对原来的list造成影响?即两个list在内存中是否存储在同一块内存空间,这也是区分深拷贝和浅拷贝的重要依据

1、赋值操作

  直接用赋值=来进行赋值,这两个列表时等价的,在内存中是同一块内存,修改其中的任何一个都会影响另一个列表

old_lsit = [1,2,3,4,[4,5,6,7]]
new_list = old_lsit

print(id(old_lsit))
print(id(new_list))
# 从打印的内存地址看 两个列表指向的内存地址完全一样,所以更改其中的任何一个对另一个就会造成影响
old_lsit[0] = 99
old_lsit[-1][0] = 66
new_list[1] = 11
new_list[-1][-1] = 88
print(old_lsit)
print(new_list)

打印结果:
14583368
14583368
[99, 11, 3, 4, [66, 5, 6, 88]]
[99, 11, 3, 4, [66, 5, 6, 88]]

2、浅拷贝

  实现浅拷贝的方法1)切片2)copy模块中的copy方法3)列表生成式

  浅拷贝之所以称为浅拷贝,原因是它只拷贝了一层,拷贝了最外围的对象本身,对于嵌套的可变数据类型,它只拷贝了其内存地址的引用

  浅拷贝分为两种情况:

  1)当浅拷贝的对象为不可变数据类型的时候,和赋值时一样的,都是拷贝的对象的引用,但是对于不可变数据对象本身来讲,当值改变时其内存地址会发生变化,所以两者不会相互影响

    

a = 10
b = copy.copy(a)
print(id(a),a)
print(id(b),b)
a = 99
print(id(a),a)
print(id(b),b)

结果:
1792898336 10
1792898336 10
1792899760 99
1792898336 10

  2)当浅拷贝的对象为list dict 集合可变数据类型的时候,当可变数据类型是单一类型没有嵌套的时候,浅拷贝也不会相互影响,只有当有嵌套的时候,比如list中嵌套list 改变嵌套的list值会相互影响

  

old_lsit = [1,2,3,4,[4,5,6,7]]
new_list = old_lsit[:]

print(id(old_lsit),old_lsit)
print(id(new_list),new_list)
old_lsit[0] = 99
old_lsit[-1][-1] =88
print(id(old_lsit),old_lsit)
print(id(new_list),new_list)
# 从打印来看 对外围的实现了深拷贝,而嵌套的list还是浅拷贝


打印结果:
1919616 [1, 2, 3, 4, [4, 5, 6, 7]]
6653952 [1, 2, 3, 4, [4, 5, 6, 7]]
1919616 [99, 2, 3, 4, [4, 5, 6, 88]]
6653952 [1, 2, 3, 4, [4, 5, 6, 88]]

 

  1)切片

  

old_lsit = [1,2,3,4,[4,5,6,7]]
new_list = old_lsit[:]

print(id(old_lsit),old_lsit)
print(id(new_list),new_list)
old_lsit[0] = 99
old_lsit[-1][-1] =88
print(id(old_lsit),old_lsit)
print(id(new_list),new_list)
# 从打印来看 对外围的实现了深拷贝,而嵌套的list还是浅拷贝


打印结果:
1919616 [1, 2, 3, 4, [4, 5, 6, 7]]
6653952 [1, 2, 3, 4, [4, 5, 6, 7]]
1919616 [99, 2, 3, 4, [4, 5, 6, 88]]
6653952 [1, 2, 3, 4, [4, 5, 6, 88]]

  2)使用copy模块中的copy函数

    

old_lsit = [1,2,3,4,[4,5,6,7]]
new_list = copy.copy(old_lsit)
print(old_lsit)
print(new_list)
old_lsit[0] = 22
old_lsit[-1][-1] = 99
print(old_lsit)
print(new_list)# 也是最外围实现了深拷贝,内部嵌套的list是浅拷贝,改变内部嵌套的list的值会相互影响
打印结果:

[1, 2, 3, 4, [4, 5, 6, 7]]
[1, 2, 3, 4, [4, 5, 6, 7]]
[22, 2, 3, 4, [4, 5, 6, 99]]
[1, 2, 3, 4, [4, 5, 6, 99]]

  3)列表生成式

  

old_lsit = [1,2,3,4,[4,5,6,7]]
new_list = [i for i in old_lsit]

print(id(old_lsit),old_lsit)
print(id(new_list),new_list)

old_lsit[0] = 99
old_lsit[-1][-1] = 100

print(id(old_lsit),old_lsit)
print(id(new_list),new_list)
打印结果:
2443904 [1, 2, 3, 4, [4, 5, 6, 7]]
7898216 [1, 2, 3, 4, [4, 5, 6, 7]]
2443904 [99, 2, 3, 4, [4, 5, 6, 100]]
7898216 [1, 2, 3, 4, [4, 5, 6, 100]]

2、深拷贝

  和浅拷贝对应,深拷贝拷贝了对象的所有元素,无论多少层嵌套,深拷贝出来是一个全新的对象,和之前的对象无任何关系

  实现方法:copy模块中的deepcopy()函数

old_lsit = [1,2,3,4,[4,5,6,7]]
new_list = copy.deepcopy(old_lsit)

print(id(old_lsit),old_lsit)
print(id(new_list),new_list)

old_lsit[0]=99
old_lsit[-1][-1] =100

print(id(old_lsit),old_lsit)
print(id(new_list),new_list)

打印结果:
11240952 [1, 2, 3, 4, [4, 5, 6, 7]]
11024984 [1, 2, 3, 4, [4, 5, 6, 7]]
11240952 [99, 2, 3, 4, [4, 5, 6, 100]]
11024984 [1, 2, 3, 4, [4, 5, 6, 7]]