一、copy(浅拷贝)
1、复制不可变数据类型(int、string、tuple)的时候,无论是copy(浅拷贝)、deepcopy(深拷贝)或者“=” 的地址都与原对象id地址一样
代码:
import copy
# 不可变类型(int、string、tuple)
a = "你好"
b = a
c = copy.copy(a) # 浅拷贝
d = copy.deepcopy(a) # 深拷贝
print("a的原地址", id(a))
print("a的赋值地址b", id(b))
print("a的浅拷贝的地址c", id(c))
print("a的深拷贝的地址d", id(d))
输出结果:
a的原地址 2500335886384
a的赋值地址b 2500335886384
a的浅拷贝的地址c 2500335886384
a的深拷贝的地址d 2500335886384
2、复制可变数据类型(list、dict)
浅拷贝有两种情况
- 第一种情况:复制的对象没有复杂的子对象,原对象的值的改变不会影响浅拷贝的对象的值,原对象的地址与浅拷贝对象的地址也不同;反之,浅拷贝的值改变也不会影响原对象的值。
代码:
import copy
list1 = [1, 2, 3, 4]
a = copy.copy(list1)
print("修改前的list1:", list1)
print("list1原地址:", id(list1))
print("list1的浅拷贝地址a:", id(a))
print("============修改原对象的值===================")
list1[0] = 5
print("修改后的list1:", list1)
print("list1修改后的地址:", id(list1))
print("修改后的list1,浅拷贝的a:", a)
print("list1修改后的浅拷贝地址a:", id(a))
输出结果:
修改前的list1: [1, 2, 3, 4]
list1原地址: 2211829200704
list1的浅拷贝地址a: 2211829200960
============修改原对象的值===================
修改后的list1: [5, 2, 3, 4]
list1修改后的地址: 2211829200704
修改后的list1,浅拷贝的a: [1, 2, 3, 4]
list1修改后的浅拷贝地址a: 2211829200960
- 第二种情况:复制的对象中有复杂的子对象,修改子对象中的值(例如列表中的一个子元素是一个列表),原对象的值的改变,浅拷贝对象中的值也跟着改变,会影响浅拷贝的值;原对象的地址与浅拷贝对象的地址不同。
代码:
import copy
list1 = [1, 2, [3, 4]]
a = copy.copy(list1)
print("修改前的list1:", list1)
print("list1原地址:", id(list1))
print("list1的浅拷贝地址a:", id(a))
print("============修改原对象的值===================")
list1[2][0] = 5
print("修改后的list1:", list1)
print("list1修改后的地址:", id(list1))
print("修改后的list1,浅拷贝的a:", a)
print("list1修改后的浅拷贝地址a:", id(a))
输出结果:
修改前的list1: [1, 2, [3, 4]]
list1原地址: 2095976298624
list1的浅拷贝地址a: 2095976214720
============修改原对象的值===================
修改后的list1: [1, 2, [5, 4]]
list1修改后的地址: 2095976298624
修改后的list1,浅拷贝的a: [1, 2, [5, 4]]
list1修改后的浅拷贝地址a: 2095976214720
二、deepcopy(深拷贝)
深拷贝是拷贝了原始对象的值并开辟了新的内存地址,新对象与原始对象是完全独立,包括内层和外层列表,原对象的值的改变不会引起新对象的值的改变。
代码:
import copy
list1 = [1, 2, [3, 4]]
b = copy.deepcopy(list1)
print("修改前的list1:", list1)
print("list1原地址:", id(list1))
print("list1的深拷贝地址b:", id(b))
print("============修改原对象的值===================")
list1[2][0] = 5
print("修改后的list1:", list1)
print("list1修改后的地址:", id(list1))
print("修改后的list1,深拷贝的a:", b)
print("list1修改后的深拷贝地址a:", id(b))
输出结果:
修改前的list1: [1, 2, [3, 4]]
list1原地址: 2081314191424
list1的深拷贝地址b: 2081314191744
============修改原对象的值===================
修改后的list1: [1, 2, [5, 4]]
list1修改后的地址: 2081314191424
修改后的list1,深拷贝的a: [1, 2, [3, 4]]
list1修改后的深拷贝地址a: 2081314191744