Python 赋值、浅拷贝、深拷贝、列表切片学习

浅拷贝,深拷贝

原文链接
提到拷贝,主要使用赋值、copy模块、列表切片、字典copy()来实现拷贝

# 赋值
# 赋值产生的拷贝是浅拷贝,共享地址。
# 改变任意一个对象中元素的值,会同时影响拷贝对象,
# 当前对象怎么变,拷贝的对象就跟着怎么变
list1 = [1,2,3,4,5]
list2 = list1
list2[0] = 100
print(list1,id(list1))
print(list2,id(list2))
# [100, 2, 3, 4, 5]  2166018012616
# [100, 2, 3, 4, 5]  2166018012616

list1 = [[1,2,3],2,3,4,5]
list2 = list1
list2[0][0] = 100
print(list1,id(list1))
print(list2,id(list2))
# [[100, 2, 3], 2, 3, 4, 5] 1932839048904
# [[100, 2, 3], 2, 3, 4, 5] 1932839048904

import copy  # 使用copy模块

# 浅拷贝
# 对于不可变类型:数字、字符串、元组, 浅拷贝仅仅是地址,
# 即就是使用相同的地址,引用相同的地址id,不会开辟新空间。
iNum = 1
iNewNum = copy.copy(iNum)
print(iNum,id(iNum))       # 1 1969923168
print(iNewNum,id(iNewNum)) # 1 1969923168

# 对于可变类型:列表、字典、集合,浅拷贝会开辟新的空间地址
# (仅仅是最外层开辟了新的空间,里层的元素地址还是相同的)
lstchild = ['a','b']
lst = [lstchild, 1, 2, 3]
lstCopy = copy.copy(lst)
print(lst,id(lst))          # [['a', 'b'], 1, 2, 3] 2419428511048
print(lstCopy,id(lstCopy))  # [['a', 'b'], 1, 2, 3] 2419428455688
print(id(lst[0]))           # 1539324376328
print(id(lstCopy[0]))       # 1539324376328
# 可以看出浅拷贝前后两个列表的地址是不同的,但是子元素列表的地址是相同的。

# 由上面可知,浅拷贝后,改变任意一个对象中不可变类型的元素的值,
# 只有当前对象受影响,不影响拷贝的对象;
# 改变任意一个对象中为可变类型的元素的值,会同时影响拷贝对象的。
lst[0][0] = 'aa'
lst[1] = 11
print(lst)        # [['aa', 'b'], 11, 2, 3]
print(lstCopy)    # [['aa', 'b'], 1, 2, 3]
# 改变lstCopy同理

# 注意:若改变任意一个对象中一个可变类型(整个,不是其中的某个元素),
# 也只会影响当前对象。
lst[0] = "ab"
print(lst)         # ['ab', 11, 2, 3]
print(lstCopy)     # [['aa', 'b'], 1, 2, 3]

# 深拷贝
# copy.deepcopy()除了外层拷贝,还对子元素也进行了拷贝(本质上递归浅拷贝),
# 原对象和拷贝对象地址不同,所有的元素地址也不同
import copy
lstchild = ['a','b']
lst = [lstchild, 1, 2, 3]
lstCopy = copy.deepcopy(lst)
print(lst,id(lst))          # [['a', 'b'], 1, 2, 3] 2096824546824
print(lstCopy,id(lstCopy))  # [['a', 'b'], 1, 2, 3] 2096824601928
print(id(lst[0]))           # 2096824547592
print(id(lstCopy[0]))       # 2096824546696

# 深拷贝后,改变任意一个对象中元素的值,只有当前对象受影响
lst[0][0] = 'aa'
lst[1] = 11
print(lst)        # [['aa', 'b'], 11, 2, 3]
print(lstCopy)    # [['a', 'b'], 1, 2, 3]

# 另外常使用的列表切片,也是浅拷贝,效果和copy.copy()相同
lstchild = ['a','b']
lst = [lstchild, 1, 2, 3]
lstCopy = lst[:]
print(lst,id(lst))          # [['a', 'b'], 1, 2, 3] 2096824546824
print(lstCopy,id(lstCopy))  # [['a', 'b'], 1, 2, 3] 2096824601928
print(id(lst[0]))           # 2685187220808
print(id(lstCopy[0]))       # 2685187220808

lst[0][0] = 'aa'
lst[1] = 11
print(lst)        # [['aa', 'b'], 11, 2, 3]
print(lstCopy)    # [['aa', 'b'], 1, 2, 3]

# 字典自带有copy()函数,这种拷贝为深拷贝
dict_ = {"a":1, "b":2}
dict_copy = dict.copy(dict_)
print(dict_, id(dict_))           # {'a': 1, 'b': 2} 1959416851840
print(dict_copy, id(dict_copy))   # {'a': 1, 'b': 2} 1959416851912
dict_["a"] = 11
dict_copy["b"] = 22
print(dict_)               # {'a': 11, 'b': 2}
print(dict_copy)          # {'a': 1, 'b': 22}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值