zoukankan      html  css  js  c++  java
  • copy 浅复制 与深复制

    python中copy模块的两个参数对比 

      先创建一个字典就搬朋友的例子来说明了

        

      >>> import copy
      >>> n1 = {"k1":123,"k2":"hehe","k3":[456,"number"]}
      >>> a = n1
      >>> b = copy.copy(n1)      #浅复制
      >>> c = copy.deepcopy(n1)    #深复制

      执行结果没有不会有什么变化

      

     >>> n1
     {'k1': 123, 'k3': [456, 'number'], 'k2': 'hehe'}
     >>> a
     {'k1': 123, 'k3': [456, 'number'], 'k2': 'hehe'}
     >>> b
     {'k1': 123, 'k3': [456, 'number'], 'k2': 'hehe'}
     >>> c
     {'k1': 123, 'k3': [456, 'number'], 'k2': 'hehe'}

      一切皆内存来看一下内存地址,结果表明 n1与 a 相同  b  c 均为独立开辟新地址 

        >>> id(n1)
        37621592
        >>> id(a)
        37621592
        >>> id(b)
        24503240
        >>> id(c)    
        37886752

      在上面的实例中使用了 copy.copy 与copy.deepcopy 对同一个字典n1 做复制操作,其中n1 字典中包含了一个字典即“k3”

      通过各键的对比可以发现,除了 c 的“k3”以外,其他变量中的键值的指针都是指向了n1的内存空间

        n1  

        >>> id(n1["k1"])
        1568402192
        >>> id(n1["k2"])
        37906752
        >>> id(n1["k3"])
        37440408
    

        a

        >>> id(a["k1"])
        1568402192
        >>> id(a["k2"])
        37906752
        >>> id(a["k3"])
        37440408
    

      

        b

        >>> id(b["k1"])
        1568402192
        >>> id(b["k2"])
        37906752
        >>> id(b["k3"])
        37440408

      

        c

        >>> id(c["k1"])
        1568402192
        >>> id(c["k2"])
        37906752
        >>> id(c["k3"])
        37430896
    

      

      上面的数据未经过修改,那先测试修改“k1”的值,将123改为456看看内存地址发生了什么变化。赋值结果已经有了区别,可以看到 n1 与 a 保持一致 b 与 c 保持一致

        >>> n1
        {'k1': 456, 'k3': [456, 'number'], 'k2': 'hehe'}
        >>> a
        {'k1': 456, 'k3': [456, 'number'], 'k2': 'hehe'}
        >>> b
        {'k1': 123, 'k3': [456, 'number'], 'k2': 'hehe'}
        >>> c
        {'k1': 123, 'k3': [456, 'number'], 'k2': 'hehe'}
    

      看一下现在的内存位置,经过对比可以发现此时更改了 “k1”的键值,变量的内存指针不会发生变化。

        >>> id(n1)
        37621592
        >>> id(a)
        37621592
        >>> id(b)
        24503240
        >>> id(c)
        37886752

      那么键值内存地址有没有发生变化呢?看一下。回顾上面的n1的“k1”结果,“k1”为37621592,当前“k1”值为37652576,这说明字典中每个键值都是由指针指向内存地址,修改过n1的“k1”值后 n1 开辟了新内存地址并将指针指向它,而且a也随着n1 的指针发生了改变。b和c依然指向之前的内存地址,这说明之前的内存地址并不会被释放,修改数据会重新开辟新的内存空间。

        >>> id(n1["k1"])
        37652576
        >>> id(a["k1"])
        37652576
        >>> id(b["k1"])
        1568402192
        >>> id(c["k1"])
        1568402192

      做了这么多貌似并没有看出 copy.copy与copy.deepcopy的区别,下面我们就来看看两者之间的区别。实例中字典里含有一个列表,现在来修改列表中的内容做对比。将“k3”的值做修改

        >>> n1
        {'k1': 456, 'k3': [8888, 'number'], 'k2': 'hehe'}
        >>> a
        {'k1': 456, 'k3': [8888, 'number'], 'k2': 'hehe'}
        >>> b
        {'k1': 123, 'k3': [8888, 'number'], 'k2': 'hehe'}
        >>> c
        {'k1': 123, 'k3': [456, 'number'], 'k2': 'hehe'}

      可以看到只有 c 没有发生改变,这是为什么呢?我想你现在已经可以理解了。做到这里就做个死得瞑目吧,接着看内存地址。

    >>> id(n1["k3"])
    37440408
    >>> id(a["k3"])
    37440408
    >>> id(b["k3"])
    37440408
    >>> id(c["k3"])
    37430896
    >>> id(n1["k3"][0]) 37652208 >>> id(a["k3"][0]) 37652208 >>> id(b["k3"][0]) 37652208 >>> id(c["k3"][0]) 37613600

     >>> id(n1["k3"][1])
     31630560
     >>> id(a["k3"][1])
     31630560
     >>> id(b["k3"][1])
     31630560
     >>> id(c["k3"][1])
     31630560

  • 相关阅读:
    CentOS 6.6 升级GCC G++ (当前最新版本为v6.1.0) (完整)
    telnet: Unable to connect to remote host: Connection refused
    bash: telnet: command not found (Linux安装telnet)
    telnet: Unable to connect to remote host: No route to host
    IP地址转换函数
    Linux 网络通信 API详解【转载】
    高效算法求解数独
    Java创建List、Map等集合对象的同时进行赋值操作
    根据先序遍历和中序遍历建立二叉树
    继承内部类时使用外部类对象.super()调用内部类的构造方法
  • 原文地址:https://www.cnblogs.com/bcode/p/6778556.html
Copyright © 2011-2022 走看看