python:赋值、切片复制、浅拷贝、深拷贝

python:赋值、切片复制、浅拷贝、深拷贝


最开始遇到这个问题是在这样一个代码里面:

a=[1,2,3]
b=a  #这里直接进行了赋值
b[0]=9
print('a:'+str(a))
print('b:'+str(b))

这个代码的输出为:

Output:
a:[9, 2, 3]
b:[9, 2, 3]

我们可以看到,当对b的元素进行更改时,a列表也发生了改变,这位是因为第二行的b=a是将a的引用赋值给了a,b和a共享同一个地址的数据,b和a也就代表最开始初始化的数据[1,2,3]的地址。
下面我们用id()函数来看一下地址变化情况:

l1=[1,2,3]
print('l1:'+str(id(l1)))
l2=[4,5,6]
print('l2:'+str(id(l2))+'\n')
l1=l2
print('l1:'+str(id(l1)))
print('l2:'+str(id(l2)))

***OUTPUT:***
l1:3089293332872
l2:3089293333384

l1:3089293333384
l2:3089293333384

l1和l2最开始分别赋值,地址不一样。但是当l1=l2之后,l1的地址就跟随l2一样了。
接下来首先引入赋值、浅拷贝深拷贝的概念:

定义

在Python中对象的赋值其实就是对象的引用。当创建一个对象,把它赋值给另一个变量的时候,python并没有拷贝这个对象,只是拷贝了这个对象的引用而已。
浅拷贝:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。也就是,把对象复制一遍,但是该对象中引用的其他对象我不复制
深拷贝:外围和内部元素都进行了拷贝对象本身,而不是引用。也就是,把对象复制一遍,并且该对象中引用的其他对象我也复制。

在切片复制下我又尝试了下面几种情况:
1. a=b[:]

l1=[1,2,3]
print('l1:'+str(id(l1)))
l2=[4,5,6]
print('l2:'+str(id(l2))+'\n')
l1=l2[:]
print('l1:'+str(id(l1)))
print('l2:'+str(id(l2)))

***OUTPUT:***
l1:1899507765640
l2:1899507766152

l1:1899537477704
l2:1899507766152

可以看到l2的地址当然没有发生改变,l1地址变成了一个新的地址。这是因为对l2进行切片,电脑就生成了一块新的地址空间来存放l2[:],l1也就成为了这个新数据的引用。

2. a[:]=b

l1=[1,2,3]
print('l1:'+str(id(l1)))
l2=[4,5,6]
print('l2:'+str(id(l2))+'\n')
l1[:]=l2
print('l1:'+str(id(l1)))
print('l2:'+str(id(l2)))

***OUTPUT:***
l1:2018877264264
l2:2018877264776

l1:2018877264264
l2:2018877264776

可以看到这种情况下,l1和l2的地址都没有发生变化,是l2把数据复制了一份到了l1里面,l1存储的地址没有变化。
3. a[:]=b[:]

l1=[1,2,3]
print('l1:'+str(id(l1)))
l2=[4,5,6]
print('l2:'+str(id(l2))+'\n')
l1[:]=l2[:]
print('l1:'+str(id(l1)))
print('l2:'+str(id(l2)))

***OUTPUT:***
l1:1330193715592
l2:1330193716104

l1:1330193715592
l2:1330193716104

可以看到,这种情况下和情况2是一样的。
所以普通的a=b是浅拷贝,切片复制是深拷贝。

但是还有一种特殊的情况,如果一个list里面包含了list,那么切片复制的规则也会发生变化:

l1=[1,2,[1,2]]
l2=[4,5,6]

l2=l1[:]
l2[0]=9
l2[2][0]=9
print('l1:'+str(l1))
print('l2:'+str(l2))

***OUTPUT:***
l1:[1, 2, [9, 2]]
l2:[9, 2, [9, 2]]

l1里的l1[2]也是一个list那么在赋值的时候l1[0]和l1[1]会把值复制一份传给l2,但是l1[2]传给l2的却是一个引用,在我们更改l2的过程中,l2[0]=9,l10位置的数字没有跟着改变,但是更改l2[2][0]=9,l1也跟着改变了。但是如果我们整体把l2[2]给换掉,那么l1不会受到影响,大家可以实验一下。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python切片是一种从给定对象中抽取部分数据的操作。拷贝是指创建一个新的对象,但是该对象的元素是对原始对象的引用。当进行切片拷贝时,我们可以通过在切片操作中使用[:]来实现。这样做可以复制原始对象的内容,并且修改副本的内容不会影响到原始对象。 在Python中,我们可以使用切片拷贝来创建一个原始对象的副本,而不是直接引用原始对象。这在某些情况下很有用,特别是当我们想要对副本进行修改而不影响原始对象时。 切片拷贝可以应用于各种可切片对象,例如列表、元组、字符串和字典等。在切片操作中,使用[:]可以复制整个对象。例如,如果我们有一个名为data的列表,我们可以使用data_copy = data[:]来创建一个拷贝。 需要注意的是,切片拷贝只是复制了对象的引用,而不是对象本身。这意味着如果原始对象包含可变的元素(例如列表),修改副本的元素将会影响到原始对象。如果需要完全独立的副本,我们可以使用拷贝。 综上所述,切片拷贝是一种通过切片操作来复制原始对象的部分或全部内容,并创建一个新的对象,该对象的元素是对原始对象的引用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Python基础(一):Python切片拷贝拷贝赋值,排序,Reduce函数](https://blog.csdn.net/xbinworld/article/details/104203829)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值