赋值、深浅拷贝
先复习一下赋值与深浅拷贝
i = [1,2,1,3,[1,2]]
j = i # 赋值
k = i.copy() # 浅拷贝
m = copy.deepcopy(i) # 深拷贝# 赋值,二者物理地址相同,一方变化另一方同步变化
j.pop(0)
print(i, j)
[2, 1, 3, [1, 2]] [2, 1, 3, [1, 2]]# 取浅拷贝,二者物理地址不同,但只是父对象不同,其中的子对象是做引用(即子对象相同)
# 如果子对象为可变类型,其变化时,会导致另一方同步变动
k.pop(0)
print(i,k)
[1, 2, 1, 3, [1, 2]] [2, 1, 3, [1, 2]]k[3].pop(0)
print(i,k)
[1, 2, 1, 3, [2]] [ 2, 1, 3, [2]]# 取深拷贝,二者父对象与子对象的物理地址都不同,完全开辟新的内存空间
m[4].pop(0)
print(i,m)
[1, 2, 1, 3, [1, 2]] [1, 2, 1, 3, [2]]
总结
- Python中所有变量都是引用(指针)
- 不可变数据发生变化时,生成新值,而不是修改原值,相同的值在内存中是唯一的
- 可变数据变化时,不会重新分配新的容器地址,只改变_容器内的变量_
- 三种拷贝方式:对于不可变数据,不管哪种拷贝,都只是快捷方式,
id
都相同。只有操作可变数据,才能体现出差异性
切片的使用
i = [1,1,2,3]
j = i
j = list(set(i)) # 为j赋予新值
print(i, j)
[1, 1, 2, 3] [1, 2, 3]i = [1,1,2,3]
j = i
j[:] = list(set(i)) # 操作j的切片
print(i, j)
[1, 2, 3] [1, 2, 3]
对一个可迭代类型使用[:]时,会生成一个与其完全相同的切片,虽然切片的地址和原对象地址不同,但使用j[:]=...用法时,是修改j的内容,不产生新的对象(切片对象仅做临时使用)