zoukankan      html  css  js  c++  java
  • python 深、浅拷贝

    Python的数据结构总体分为两类:

    1、字符串和数字

    2、列表、元组、字典等

    一、字符串和数字

      对于字符串和数字而言,赋值(=)、浅拷贝(copy)和深拷贝(deepcopy)其实都没有意义,因为它们都永远指向同一个内存地址。

    >>> import copy
    >>> a1 = 100
    >>> id(a1)
    1426656816   # a1的内存地址
    
    # 赋值
    >>> a2 = a1
    >>> id(a2)
    1426656816
    
    # 浅拷贝
    >>> a3 = copy.copy(a1)
    >>> id(a3)
    1426656816
    
    # 深拷贝
    >>> a4 = copy.deepcopy(a1)
    >>> id(a4)
    1426656816
    

      如图:

     

    二、列表、元组、字典等

      对于列表、字典而言,进行赋值(=)、浅拷贝(copy)和深拷贝(deepcopy),其引起的变化是不一样的。

    2.1、赋值(=) 

    names = ['Angle', 'Zous', 'Athena', ['Banana', 'apple']]
    name2 = names
    names[1] = "Pear"
    print(names)
    print(name2)
    print("-----------------")
    names[3][1] = "Dog"
    print(names)
    print(name2)
    print(id(names))
    print(id(name2))
    
    
    # 输出
    ['Angle', 'Pear', 'Athena', ['Banana', 'apple']]
    ['Angle', 'Pear', 'Athena', ['Banana', 'apple']]
    -----------------
    ['Angle', 'Pear', 'Athena', ['Banana', 'Dog']]
    ['Angle', 'Pear', 'Athena', ['Banana', 'Dog']]
    1504387406536
    1504387406536
    
    # 可以看到names 的每一次变化,name2也会改变,因为他们的内存地址是一样的
    

      如图:

      

      这和字符串和数字是不一样的,当我们定义 a =1 ,b = a ,改变a时,b是不会有变化的。列表和字典等会跟着变化,因为他们的内存地址是一样的。  

    a = 1
    b = a  
    a = 100
    print(a)
    print(b)
    
    # 输出
    
    100
    1
    

      

    2.2、浅拷贝(copy) 

    import copy
    
    names = ['Angle', 'Zous', 'Athena', ['Banana', 'apple']]
    name2 = copy.copy(names)
    names[1] = "宙斯"
    print(names, "names的内存地址是{}".format(id(names)))
    print(name2, "name2的内存地址是{}".format(id(name2)))
    
    #输出
    ['Angle', '宙斯', 'Athena', ['Banana', 'apple']] names的内存地址是1764417452744
    ['Angle', 'Zous', 'Athena', ['Banana', 'apple']] name2的内存地址是1764416035080
    
    我们浅copy了一个name2,同时我们将names中的Zous的值改为中文,但是name2的没有改变。因为他们的内存地址是不一样的,改变其中一个不影响另外一个。
    

      我们接下来看:

    import copy
    
    names = ['Angle', 'Zous', 'Athena', ['Banana', 'apple']]
    name2 = copy.copy(names)
    names[1] = "宙斯"
    print(names, "names的内存地址是{}".format(id(names)))
    print(name2, "name2的内存地址是{}".format(id(name2)))
    
    names[3][1] = '苹果'
    print(names, id(names[3]))
    print(name2, id(name2[3]))
    
    # 输出
    ['Angle', '宙斯', 'Athena', ['Banana', 'apple']] names的内存地址是2306153560776
    ['Angle', 'Zous', 'Athena', ['Banana', 'apple']] name2的内存地址是2306152155528
    ['Angle', '宙斯', 'Athena', ['Banana', '苹果']] 2306153648968
    ['Angle', 'Zous', 'Athena', ['Banana', '苹果']] 2306153648968
    
    # 这次我们不仅改变了最外层的列表的值,还改变了列表中一个列表的值。
    # 这次的结果是  里层的列表跟着做了改变
    

      我们通过打印的内存地址可以明显看出,整个外层列表的内存地址是不一样的,但是里层的列表内存地址是一致的。

           如图:

      

      总结:浅拷贝(copy.copy(x))只是将列表等数据类型的第一层copy了一下,内存地址改变了。但是对于里层的数据类型的内存地址没有改变。

    2.3、深拷贝(deepcopy)

      深拷贝(copy.deepcopy(x))其实就是重新开辟了一个新的内存地址,存储deepcopy后的数据,和原来数据的内存地址完全不一样了,包括里层数据类型的内存地址。 

    import copy
    
    names = ['Angle', 'Zous', 'Athena', ['Banana', 'apple']]
    name2 = copy.deepcopy(names)
    names[1] = "宙斯"
    print(names, "names的内存地址是{}".format(id(names)))
    print(name2, "name2的内存地址是{}".format(id(name2)))
    
    names[3][1] = '苹果'
    print(names, id(names[3]))
    print(name2, id(name2[3]))
    
    #输出
    ['Angle', '宙斯', 'Athena', ['Banana', 'apple']] names的内存地址是2379824216776
    ['Angle', 'Zous', 'Athena', ['Banana', 'apple']] name2的内存地址是2379824217160
    ['Angle', '宙斯', 'Athena', ['Banana', '苹果']] 2379824304968
    ['Angle', 'Zous', 'Athena', ['Banana', 'apple']] 2379824305032
    
    #可以看出,names不论是改变外层还是里层列表的数据,都不会影响到name2。
    

      如图:

      

  • 相关阅读:
    [原创] Laravel 启动流程
    修改电脑的TTL返回值
    Apache启动错误解决方法
    RemodelanyWhere11.0.2673版本下载
    函数指针
    指针与数组
    青蛙跳台阶
    旋转数组的最小数字
    对大量人的年龄排序
    泛型算法一
  • 原文地址:https://www.cnblogs.com/bigberg/p/7246756.html
Copyright © 2011-2022 走看看