python核心--赋值、浅拷贝、深拷贝

赋值、浅拷贝、深拷贝

python的深浅拷贝之前我学习过,直到今天我才发现我对深浅拷贝、赋值有一个误区。所以我想写篇文章来纠正一下自己,也提醒新学的人不要犯我的错误。

1.赋值

我之前以为,赋值是这样的。给大家画个图

a = [1, 2, 3]
b = a
print(a, b)

直到今天我发现原来赋值是这样的

print(id(a), id(b))

  解释:两个id一样,那是不是说明赋值并没有创建一个新的对象,a,b公用一个对象,即如下图所示。

2.浅拷贝

把赋值的真正含义弄懂了,那浅拷贝就容易多了。浅拷贝:只拷贝父对象,不会拷贝对象的内部的子对象。这么说会有点抽象,那么举个例子来说明,就容易理解多了。

import copy
a = [1,2,3]
b = copy.copy(a)
print(id(a),id(b))
print(a,b)

  结果:

  2811085694088     2811085694280

  [1, 2, 3]     [1, 2, 3]

  解释:

  我们可以看到两个id是不相同的,说明是两个不同的对象

    

如果是那样的话,再举一个例子。来验证验证我的想法。

import copy
a = [1,2,[3]]
b = copy.copy(a)
a.append(4)
print(a,b)

  输出结果:

    我想的 :[1, 2, [3], 4]  [1, 2, [3], 4]

    实际的:[1, 2, [3], 4] [1, 2, [3]]

我有点懵逼,是我哪里搞错了?难道不应该是我想的那样?

浅拷贝难道不是拷贝的是原来列表的地址么?后来通过看书我才明白了,浅拷贝真正拷贝的是容器元素的地址。那我们再举个例子看一下。

import copy
a = [1,2,[3]]
b = copy.copy(a)
for x in a:
    print(id(x))
for y in b:
    print(id(y))    

  结果输出:

    1431797872  1431797904  1774225499272

    1431797872  1431797904  1774225499272    (是拷贝的元素id没错吧)

当我们给a新添加一个元素时,a就产生了一个新的元素id,在当这之前b已经拷贝走了,所以它不知道。

当我们给一个已经存在的元素里再添加一个元素,就比如[1,2,[3]]的[3]添加一个元素时,它的id会不会变?答案是当然不会变,那么在b中就能看到这个元素。 下面我们举个例子吧

i

import copy
a = [1,2,[3]]
b = copy.copy(a)
a.append(4)
print(a,b)

  输出结果:

  [1, 2, [3], 4]   [1, 2, [3]]  (因为新添加的元素产生了一个新的id)

在这里考大家一个小题目:

b = a[:]  这个是浅拷贝呢  还是赋值呢?

答案:浅拷贝,因为他不仅仅是赋值了引用值,还把a里的元素(也就是id)传了进去。

3.深拷贝

深拷贝就很接近我们生活中理解的那个复制、粘贴一样,它拷贝了一个副本。就是b把a里的元素全部复制了一遍,自己新弄了一个。

import copy
a = [1,2,[3]]
b = copy.deepcopy(a)
for x in a:
    print(id(x))
for y in b:
    print(id(y))

  输出结果:

  1431797872   1431797904    1701157119112

  1431797872   1431797904    1701157112486  

大家发现了应该是三个id不一样啊,但是为什么前两个一样。我就想着如果我修改a中第二个元素的值,那b会不会改变?如果是完全拷贝的话,那肯定不会改变。

import copy
a = [1,2,[3]]
b = copy.deepcopy(a)
a[1]=111
print(a,b)

  结果输出: [1, 111, [3]] [1, 2, [3]]   (没有改变是拓过来的一个样本)

之所以会出现id一样的情况,我认为是为了系统之间为了节省内存,一样的东西不会占用两个内存。

4.跳坑

1.大家知道元组里的元素是不可遍历的。如果想深拷贝元组里的元素,是不行的。

2.对于数字、字符串这种元素,它是不能拷贝的。

5.总结

   1. 赋值是将一个对象的地址赋值给了另一个一个变量,这两个变量都指向该地址。

 2. 浅拷贝是创建了一个新的变量,但是里面的元素是源对象的元素的地址。

 3. 深拷贝是创建一个新的变量,里面的元素的地址也是新的,仅仅是值相同而已。(相当于生活中的复制粘贴)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值