Python浅拷贝与深拷贝 -- 创建数组时引发的问题

本文详细解释了Python中浅拷贝和深拷贝的概念,通过实例展示了直接赋值、浅拷贝和深拷贝的区别。重点讨论了[[0]*m]*n与[[0 for _ in range(m)] for _ in range(n)]在初始化二维数组时的不同行为,指出前者可能导致意外的共享引用问题,而后者则能创建独立的全新数组。
摘要由CSDN通过智能技术生成

浅拷贝与深拷贝 - - [[0]*m]*n与[[0 for _ in range(m)] for _ in range(n)]的区别

最近刚开始转用python刷题,今天刷到718. 最长重复子数组。用了dp,又看了看评论区的代码,发现基本一样,可是结果就是不对…感觉特别懵逼,后来注意到创建dp数组的语句不太一样,就想可不可能是这个问题,一改果然对了。查看相关资料后,发现原来这是python深拷贝与浅拷贝的区别。

python的浅拷贝与深拷贝

三种方式:
a=[[0,1,2,3],[4,5,6,7],[8,9,10,11]]
b=a
c=a.copy()
d=copy.deepcopy(a)

1.直接赋值(b=a), 即对象的引用,也就是别名;

2.浅拷贝(c=a.copy), 只拷贝父对象,不会拷贝对象的内部的子对象。
(就是只拷贝了外面这一层,a[0],a[1],a[2],里面这三个里面的元素还是相当于引用。
不拷贝子对象即子对象还是引用,如果a[0][1]+=1, c即使不做操作,c打印出来c[0][1]也会变成2。再有,对于拷贝父对象就是,如果a外面这一层加了一个a[3],a.append([12,13,14,15]),c打印出来是不会加上这个[12,13,14,15]的)

3.深拷贝(d=copy.deepcopy(a))。copy模块的deepcopy方法,完全拷贝了父对象和子对象。
(就是一个全新的数组,和原来的互不相干,谁变了都不会影响谁)

示例

import  copy
a=[[0,1,2,3],[4,5,6,7],[8,9,10,11]]
b=a # 直接赋值,对象的引用,相当于别名
c=a.copy() # 浅拷贝,只拷贝父对象,子对象不拷贝
d=copy.deepcopy(a) # 深拷贝,父子对象都拷贝

a[0][1]+=1
a.append([12,13,14,15])

print("a:",a) # 原数组
print("b:",b) # 引用,和a相同,a的别名
print("c:",c) # 浅拷贝,外面一层父对象是拷贝,里面的子对象不拷贝,还是引用
print("d:",d) # 深拷贝,父子对象都拷贝,相当于全新的数组,和a不相干,只是复制了a的值

输出:
a: [[0, 2, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]
b: [[0, 2, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]
c: [[0, 2, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
d: [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]

[[0]*m]*n与[[0 for _ in range(m)] for _ in range(n)]的区别

[0]*m,[[0]*m]*n属于直接赋值。所以当a[1][1]+=1时,a[0][1]即使不做操作,也会变得和a[1][1]一样。

而[[0 for _ in range(m)] for _ in range(n)]就是真正的初始化创建一个全新的数组。

l=[0]*3
print(l)
l[0]=2
print(id(l[0]),id(l[1]),id(l[2]))
print(l)

l=[[0]*3]*4
print(l)
l[0][1]+=1
print(id(l[0]),id(l[1]))
print(id(l[0][0]),id(l[0][1]),id(l[0][2]))
print(id(l[1][0]),id(l[1][1]),id(l[1][2]))
print(l)

输出:
[0, 0, 0]
140715356469088 140715356469024 140715356469024
[2, 0, 0]
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
2361970042752 2361970042752
140715356469024 140715356469056 140715356469024
140715356469024 140715356469056 140715356469024
[[0, 1, 0], [0, 1, 0], [0, 1, 0], [0, 1, 0]]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值