# author
# date 2022/5/10 - 10:13
# difference between '==' and 'is'
# "==" compare the value of an object
# "is" judge two variable is the same , id(variable)
a = 10
b = 10
print(a == b) # True
print(a is b) # True
print(id(a)) # 140737281630896
print(id(b)) # 140737281630896
# 对于不可变对象, 例如,字符或元组
t1 = (1, 2, [3, 4]) # 元组对象中包含可变元素-列表
t2 = (1, 2, [3, 4])
print(t1 == t2) # True
print(t1 is t2) # False
t1[-1].append(5)
print(t1) # (1, 2, [3, 4, 5])
# 说明虽然元组对象是不可变的,但是里面还有可变对象的元素,
# 可以修改元组元素
"""
shallow copy and deep copy
shallow copy : 浅拷贝,是指重新分配一块内存,创建一个新的对象,
里面的元素是源对象中子对象的引用。因此,如果源对象中的元素不可变,对浅拷贝出的新对象无影响
但是,要注意,浅拷贝通常会有一些副作用
可以通过list(), tuple(), set(),dict() 等函数实现对象的浅拷贝
也可以通过切片[:] 实现对象的浅拷贝
"""
l1 = [1, 2, 3]
l2 = list(l1)
print(l2) # [1, 2, 3]
print(l1 == l2) # True
print(l1 is l2) # False
s1 = {1, 2, 3}
s2 = set(s1)
print(s2) # {1, 2, 3}
print(s2 == s1) # True
print(s2 is s1) # False
# 说明: l2 is the shallow copy of l1
# s2 is the shallow copy of s1
l1 = [1, 2, 3] # True
l2 = l1[:] # False 对于可变序列,可以通过切片“:“ 完成浅拷贝
print(l1 == l2)
print(l2 is l1)
# 元组对象
t1 = (1, 2, 3)
t2 = t1[:]
print(t2 is t1) # True
# 对于元组,使用tuple()或切片操作符[:] 不会创建一份浅拷贝
# 相反,它会返回一个指向相同元组的引用
# python中提供了响应的函数 copy.copy(),实现对象的浅拷贝,适用于任何数据类型
import copy
l1 = [1, 2, 3]
l2 = copy.copy(l1)
print(l2 is l1) # False
# 浅拷贝的一些副作用
l1 = [[1, 2], [30, 40]]
l2 = copy.copy(l1)
l1.append(100) # 对l1列表新增元素,该操作对l2无影响
l1[0].append(3)
print(l1) # [[1, 2, 3], [30, 40], 100]
print(l2) # [[1, 2, 3], [30, 40]]
l1[1] += (50, 60) # 由于元组是不可变的,对列表l1中的第二个元组对象拼接,
# 然后创建了一个新元组作为l1中的第二个元素, 而l2中没有引用新元组,
# 因此l2不受影响
# 此处 元组的+=操作可以类比字符的+=操作,
s = "my name"
print(id(s))
s = s + ' is'
print(id(s))
print(s) # 其中s的改变并不是真正的修改了s变量,而是重新创建了一个s变量
print(l1) # [[1, 2, 3], [30, 40, 50, 60], 100]
print(l2) # [[1, 2, 3], [30, 40]]
# 上述代码,初始化了一个列表l1,里面的元素低一个列表和一个元组;
# 然后对l1指向浅拷贝,赋予l2, 因为浅拷贝里的元素是对源对象的引用,
# 因此l2中的元素和l1指向同一个列表和元组对象
# 深拷贝 l2 是 l1 的深拷贝对象,l2与l1之间完全独立
l1 = [[1, 2], [30, 40]]
l2 = copy.deepcopy(l1)
l1.append(100)
l1[0].append(3)
print(l1) # [[1, 2, 3], [30, 40], 100]
print(l2) # [[1, 2], [30, 40]]
l1[1] += (30, 40)
print(l1) # [[1, 2, 3], [30, 40, 30, 40], 100]
print(l2) # [[1, 2], [30, 40]]
# 深度拷贝并不是完美的,如果被copy对象中存在指向自身的引用,程序容易陷入无限循环
x = [1]
x.append(x) # [1, [...]]
print(x)
y = copy.deepcopy(x)
print(y) # [1, [...]]
Python - shallow copy and deepcopy
最新推荐文章于 2024-08-05 23:13:57 发布