关于python赋值的迷思

2019-03-10  本文已影响0人  lutl

参考链接
写这篇文章的原因在于写链表逆序时看到的python代码,语法糖真香啊,同时也发现了自己对python赋值方面的错误理解

一、 题目及python代码

链表节点两两互换leetcode

def swapPairs(self, head):
    pre, pre.next = self, head
    while pre.next and pre.next.next:
        a = pre.next
        b = a.next
        pre.next, b.next, a.next = b, a, b.next
        pre = a
    return self.next

对于函数中对self的操作,以后有时间再写

二、 赋值举例

1. 下例的连续赋值,起到了交换变量a, b的作用,但实际上真的只是变量交换吗

>>> a = 1
>>> b = 3
>>> a, b
(1, 3)
>>> a, b = b, a
>>> a, b
(3, 1)

2. 大家觉得应该是(1, 3)还是(1, 1)呢

>>> a = 3
>>> b, a = a, 1
>>> a, b
(1, 3)

3. 是不是如果不用切片复制的话就有点不如人意

>>> values = list(range(1,5))
>>> values[2] = values
>>> values
[1, 2, [...], 4]
# 使用切片复制
>>> values[2] = values[:]
>>> values
[1, 2, [1, 2, 3, 4], 4]

4. 用了切片复制,列表b的值还是被改变了

>>> a = [0, [1, 2], 3]
>>> b = a[:]
>>> a[0] = 8
>>> a[1][1] = 9
>>> a
[8, [1, 9], 3]
>>> b
[0, [1, 9], 3]

5. 使用deepcopy才能不干扰

>>> import copy
>>> a = [0, [1, 2], 3]
>>> b = copy.deepcopy(a)
>>> a[0] = 8
>>> a[1][1] = 9
>>> a
[8, [1, 9], 3]
>>> b
[0, [1, 2], 3]

三、牵扯出来的顶层复制以及深拷贝的问题

  1. python中的变量当作引用来理解的话,所有问题都可以迎刃而解
  2. 对于连续赋值的问题,它并不是从右到左依次赋值,理解为右侧的内存地址一次性赋值到左侧,这可以解释2.1与2.2的疑惑
  3. 如果不使用切片复制的话,相当于values中的元素引用了本身,构成了循环
  4. 切片复制、字典copy方法都属于顶层复制,只有最上层的数据不会被更改,这是2.4中列表b被修改的原因
  5. deepcopy函数是深拷贝,其实是递归拷贝,不会产生数据被顺道修改的问题

如果看完文章还有哪里有疑问,可以看文章开头的参考链接,非常的详细

上一篇下一篇

猜你喜欢

热点阅读