• list深拷贝和浅拷贝


    在Python中,经常要对一个list进行复制。对于复制,自然的就有深拷贝与浅拷贝问题。深拷贝与浅拷贝的区别在于,当从原本的list复制出的list之后,修改其中的任意一个是否会对另一个造成影响,即这两个list在内存中是否储存在同一个区域,这也是区分深拷贝与浅拷贝的重要依据。接下来我们就针对Python中list复制的几种方法,来探究一下其是属于深拷贝还是浅拷贝。弄清楚这个问题,有助于我们在编程中规避错误,减少不必要的调试时间。

    一、非拷贝方法——直接赋值

      如果用=直接赋值,是非拷贝方法。这两个列表是等价的,修改其中任何一个列表都会影响到另一个列表。这也是Python作为动态语言与C这类静态语言在思想上的不同之处。

    复制代码
    old = [1,[1,2,3],3]
    new = old
    print('Before:')
    print(old)
    print(new)
    new[0] = 3
    new[1][0] = 3
    print('After:')
    print(old)
    print(new)
    复制代码

    运行结果如下:

    二、浅拷贝的几种方法

    1.copy()方法

      我们来看以下代码:

    复制代码
    old = [1,[1,2,3],3]
    new = old.copy()
    print('Before:')
    print(old)
    print(new)
    new[0] = 3
    new[1][0] =3
    print('After:')
    print(old)
    print(new)
    复制代码

    运行结果如下:

      

      对于list的第一层,是实现了深拷贝,但对于嵌套的list,仍然是浅拷贝。这其实很好理解,内层的list保存的是地址,复制过去的时候是把地址复制过去了。嵌套的list在内存中指向的还是同一个。 

    2.使用列表生成式

      使用列表生成式产生新列表也是一个浅拷贝方法,只对第一层实现深拷贝。

    复制代码
    old = [1,[1,2,3],3]
    new = [i for i in old]
    print('Before')
    print(old)
    print(new)
    new[0] = 3
    new[1][0] = 3
    print('After')
    print(old)
    print(new)
    复制代码

    运行结果如下:

      

    3.用for循环遍历

      通过for循环遍历,将元素一个个添加到新列表中。这也是一个浅拷贝方法,只对第一层实现深拷贝。

    复制代码
    old = [1,[1,2,3],3]
    new = []
    for i in range(len(old)):
        new.append(old[i])
    print('Before:')
    print(old)
    print(new)
    new[0] = 3
    new[1][0] = 3
    print('After:')
    print(old)
    print(new)
    复制代码

    运行结果如下:

      

    4.使用切片

      通过使用[:]切片,可以浅拷贝整个列表。同样的,只对第一层实现深拷贝。

    复制代码
    old = [1,[1,2,3],3]
    new = old[:]
    print('Before:')
    print(old)
    print(new)
    new[0] = 3
    new[1][0] = 3
    print('After:')
    print(old)
    print(new)
    复制代码

    运行结果如下:

      

    三、深拷贝的实现

      如果用deepcopy()方法,则无论多少层,无论怎样的形式,得到的新列表都是和原来无关的,这是最安全最清爽最有效的方法。

      使用时,要导入copy。

    复制代码
    import copy
    old = [1,[1,2,3],3]
    new = copy.deepcopy(old)
    print('Before:')
    print(old)
    print(new)
    new[0] = 3
    new[1][0] = 3
    print('After:')
    print(old)
    print(new)
    复制代码

    运行结果如下:

    来源:https://www.cnblogs.com/Black-rainbow/p/9577029.html

  • 相关阅读:
    *** mixed implicit and normal rules: deprecated syntax
    cold boot and warm boot.
    git打补丁命令
    LSB和MSB
    __attribute__((weak)) ------ 关于弱符号的用法
    键盘和鼠标无法热插拔问题
    yocto编译加速及单独编译内核与uboot
    V4L2学习教程
    linux错误码
    linux内核面试常见试题
  • 原文地址:https://www.cnblogs.com/wisir/p/11070277.html
Copyright © 2020-2023  润新知