python中有关赋值的问题

众所周知,Python的赋值和一般的高级语言的赋值有很大的不同,它是引用赋值。看下面的代码1:

  >>>a = 5

  >>>b = 8

  >>>  a = b    #结果如下图1:

图1

  开始的时候a指向的是5,b指向的是8,当a = b的时候,b把自己指向的地址(也就是8的内存地址)赋给了a,那么最后的结果就是a和b同时指向了8。我们可以用Python内建的函数id()来测试

 那好,现在我们来看下一种情况: 

>>>a = [1,2,3] 

>>>id(a )               #可以得到1217620

>>>a.append(4)    #这时候a = [1,2,3,4],

>>>id(a)                #结果还是1217620,证明如果是添加对象,不改变变量的内存地址,这个是我们下面要探讨的问题的先决条件。

>>>b = a               # b = [1,2,3,4]

>>>a.append(5)    #a = b = [1,2,3,4,5]

如果没有上面的结论,[1,2,3,4]的地址和[1,2,3]的地址不一样,那么最终的结果是 a = [1,2,3,4,5], b = [1,2,3,4]

那怎么才能够让a变成[1,2,3,4],而b仍然是[1,2,3]呢? 这个时候我们需要用到copy,也就是拷贝,python内置了copy模块。看代码2

>>>import copy

>>>a = [1,2,3] 

>>>b = copy.copy(a)   #这个时候a = b = [1,2,3]

>>>a.append(4)          # a = [1,2,3,4],b = [1,2,3]

事情到这里好像就结束了,但是问题又来啦,看下面的代码3

>>>import copy

>>>a = [1,2,[3,4]]

>>>b = copy.copy(a)

>>>id(a)                    #12177080

>>>id(b)                    #12186888,证明a、b指向的不是同一个地址

>>>a[2].append(5)    # 这时候a = b = [1,2,[3,4,5]],怎么会这样????

>>>id(a[0])                # 100380032

>>>id(b[0])                # 100380032 二者是共享地址的

也就是说这个copy.copy复制的不彻底,只复制了对象,对象的属性却是共享的。那我们有别的方法没?答案是肯定的,看下面的代码4

>>>import copy

>>>a = [1,2,[3,4]]    

>>>b = copy.deepcopy(a)

>>>id(a)                      #12177080

>>>id(b)                      #12177000

>>>a[2].append(5)     #这时候 a = [1,2,[3,4,5]],而 b = [1,2,[3,4]]

>>>id(a[2][1])             #10379996

>>>id(b[2][1])             #10379996     这两个还是一样的,大惑不解,这是为什么?求达人解惑 

经过linvo同学的指点,现在明白了为什么是这样。下面画个图:

如果只是浅拷贝(copy.copy),那么虚线部分是不会赋值给b的,只是把 [3,4]这个列表整体赋值。所以结果如代码3所示

而如果是深拷贝(copy.deepcopy),那么会把列表[3,4]的具体成员也赋给b,这也解释了代码4的疑惑

未完待续。。。。。。。。。。。。。。。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值