Python教程

python高级(二):浅拷贝与深拷贝

本文主要是介绍python高级(二):浅拷贝与深拷贝,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

浅拷贝和深拷贝

浅拷贝:对引用的拷贝,拷贝的是地址。原对象中的可变类型改变,拷贝也会改变。不可变类型改变,拷贝不变。
深拷贝:对对象的资源的拷贝,拷贝的是值。原对象改变,拷贝对象不会改变

首先,对赋值操作我们要有以下认识:

  1. 赋值是将一个对象的地址赋值给一个变量,让变量指向该地址( 旧瓶装旧酒 )。
  2. 修改不可变对象(str、tuple)需要开辟新的空间
  3. 修改可变对象(list等)不需要开辟新的空间

浅拷贝

  • 浅拷贝仅仅复制了容器中元素的地址
import copy

a = ['hello', [1, 2, 3]]
b = copy.copy(a)
print('原容器:', a, '地址:', [id(i) for i in a])
print('浅拷贝:', b, '地址:', [id(j) for j in b])

原容器: ['hello', [1, 2, 3]] 地址: [2719850669312, 2719853248072]
浅拷贝: ['hello', [1, 2, 3]] 地址: [2719850669312, 2719853248072]

  • 浅拷贝--当不可变类型的值改变的时候,地址改变,浅拷贝取原地址的值,所以不变。当可变类型的值改变时,地址不变,所以浅拷贝中的元素相应改变。
import copy

a = ['hello', [1, 2, 3]]
b = copy.copy(a)
print('原容器:', a, '地址:', [id(i) for i in a])
print('浅拷贝:', b, '地址:', [id(j) for j in b])

a[0] = 'world'
a[1].append(4)
print('原容器修改后:', a, '地址:', [id(i) for i in a])
print('原容器修改后的浅拷贝:', b, '地址:', [id(j) for j in b])

原容器修改后: ['world', [1, 2, 3, 4]] 地址: [2719850669480, 2719853248072]
原容器修改后的浅拷贝: ['hello', [1, 2, 3, 4]] 地址: [2719850669312, 2719853248072]

总结
浅拷贝是在另一块地址中创建一个新的变量或容器,但是容器内的元素的地址均是源对象的元素的地址的拷贝。也就是说新的容器中指向了旧的元素( 新瓶装旧酒 )。

深拷贝

  • 深拷贝完全拷贝了一个副本
import copy

a = ['hello', [1, 2, 3]]
c = copy.deepcopy(a)
print('原容器:', a, '地址:', [id(i) for i in a])
print('深拷贝:', c, '地址:', [id(j) for j in c])

原容器: ['hello', [1, 2, 3]] 地址: [3100654871808, 3100657450568]
深拷贝: ['hello', [1, 2, 3]] 地址: [3100654871808, 3100657450248]

  • 深拷贝--修改原容器中的元素,不影响深拷贝
import copy

a = ['hello', [1, 2, 3]]
c = copy.deepcopy(a)
print('原容器:', a, '地址:', [id(i) for i in a])
print('深拷贝:', c, '地址:', [id(j) for j in c])
a[0] = 'world'
a[1].append(4)
print('原容器修改后:', a, '地址:', [id(i) for i in a])
print('原容器修改后深拷贝:', c, '地址:', [id(j) for j in c])

原容器修改后: ['world', [1, 2, 3, 4]] 地址: [3100654871976, 3100657450568]
原容器修改后深拷贝: ['hello', [1, 2, 3]] 地址: [3100654871808, 3100657450248]

总结
深拷贝是在另一块地址中创建一个新的变量或容器,同时容器内的元素的地址也是新开辟的,仅仅是值相同而已,是完全的副本。也就是说( 新瓶装新酒 )。

这篇关于python高级(二):浅拷贝与深拷贝的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!