zoukankan      html  css  js  c++  java
  • 关于python中深拷贝与浅拷贝问题

    关于python中深拷贝与浅拷贝问题,做个研究小结。

    《python核心编程》上说:

    以存储模型为标准,类型可以分为:

    标量/原子类型 数值(所有的数值类型)、字符串(全部文字)

    容器类型 列表、元组、字典

    以更新模型为标准,类型可以分为:

    可变类型:列表,字典

    不可变类型:数字,字符串,元组

    可变类型创建后允许值更新,不可变类型创建后不允许值更新。不可变类型创建新对象后若与旧对象重名,就会取代旧对象,比如:

    x = 'Hello!'
    id(x)
    32074688
    x = 'Hi'
    id(x)
    32014136
    i = 0
    id(i)
    20069076
    i = 1
    id(i)
    20069064

    再深入研究就是深拷贝和浅拷贝。

    浅拷贝是默认的拷贝类型,序列类型的可以通过三种方式实现浅拷贝:1、完全切片操作;2、利用工厂函数,比如list()等;3、使用copy模块中的copy()函数。对于非容器类型没有拷贝这一说。“对一个对象进行浅拷贝其实是新创建了一个类型跟原对象一样,其内容是原来对象元素的引用,换句话说,这个拷贝的对象本身是新的,但是它的内容不是。”用一个例子作解释:

    a = [1,2,[3,4],5]
    b = list(a)
    id(a)
    32082040
    id(b)
    32084416
    [id(x) for x in a]
    [20069064, 20069052, 32084576, 20069016]
    [id(x) for x in b]
    [20069064, 20069052, 32084576, 20069016]

    可以看到b作为浅拷贝创立的新对象,与a的地址不同(id()结果可以认为是内存地址),但是其内容数据的地址却是一致的,符合上述解释。

    再进一步分析:

    a = [1,2,[3,4],5]
    b = list(a)
    a[0] = 100
    a
    [100, 2, [3, 4], 5]
    b
    [1, 2, [3, 4], 5]
    b[0] = 'tt'
    a
    [100, 2, [3, 4], 5]
    b
    ['tt', 2, [3, 4], 5]
    a[2][0] = 30
    a
    [100, 2, [30, 4], 5]
    b
    ['tt', 2, [30, 4], 5]
    b[2][1] = 40
    b
    ['tt', 2, [30, 40], 5]
    a
    [100, 2, [30, 40], 5]
    可以看到浅拷贝后的b和原值a之间有某种联系。具体表现在其嵌套结构中数据似乎是引用关系,一个改变,另外一个也跟着改变,例如a[2][0]、b[2][1]更改之后的表现。所以有人说“浅拷贝只能做顶层复制,但是不能复制其嵌套的数据结构。”我觉得这个说法可以接受,至少目前自己找不到更好的解释。

    那么如果不想复制数据后还存在这种相互引用关系该怎么办呢?用copy.deepcopy()方法。

    import copy
    a = [1,2,[3,4],5]
    b = copy.deepcopy(a)
    a[2][0] = 30
    a
    [1, 2, [30, 4], 5]
    b
    [1, 2, [3, 4], 5]
    b[2][1] = 40
    a
    [1, 2, [30, 4], 5]
    b
    [1, 2, [3, 40], 5]

    参考:http://www.cnblogs.com/wait123/archive/2011/10/10/2206580.html

        http://www.oschina.net/question/872916_84343


  • 相关阅读:
    JavaScript与C# Windows应用程序交互
    用DateTime.ToString(string format)输出不同格式的日期
    时间间隔与暂停
    C#中比较两个时间的时间差
    lambda函数的用法
    Tornado笔记
    DjangoWeb应用开发实战笔记
    再看装饰器
    描述符
    flask简单代码回顾
  • 原文地址:https://www.cnblogs.com/Harry-Lord/p/4002857.html
Copyright © 2011-2022 走看看