• Python 深浅复制


    (一)浅复制

    复制列表最简单的方式是使用内置类型的构造方法:

    >>> l1 = [1, [2, 3], (4, 5)]
    >>> l2 = list(l1)
    >>> l2
    [1, [2, 3], (4, 5)]
    >>> l2 is l1
    False
    >>> l2 == l1
    True

    对于列表和其他可变序列来说,也可以使用[:]:

    >>> l3 = l1[:]
    >>> l3
    [1, [2, 3], (4, 5)]
    >>> l3 is l1
    False
    >>> l3 == l1
    True

    然而构造方法和[:]都是浅复制,其复制原理如下图所示:

    在上面的列表中,有元素是可变的,这可能导致意想不到的问题:

    比如我们现在执行语句 l1[1].remove(2) 

    其结果如下图:

    对l1的remove操作同时会影响l2, 

    我们再试试对l2的的元素操作: l2[1] += [22],其结果如下:

     

    同样的,对l2的操作影响l2.

    当我们对l1里的元组进行+=操作后,结果如下:

    对于元组来说,它本身是不可变序列, +=运算符创建了一个新元组,然后重新绑定给了变量l1[2], l1, l2中最后位置上的元组不是同一个对象

    (二)深复制

     默认浅复制没有什么问题,但是有时候我们需要深复制,copy模块提供了deepcopy和copy函数,它们可以为任意对象做深复制和浅复制

    下面演示deepcopy和copy的区别:

    先定义Bus类如下:

    class Bus:
        def __init__(self, passengers=None):
            if passengers is None:
                self.passengers = []
            else:
                self.passengers = list(passengers)
    
        def pick(self, name):
            self.passengers.append(name)
    
        def drop(self, name):
            self.passengers.remove(name)

    然后在控制台使用copy和deepcopy分别对Bus类的实例进行操作:

    >>> from Example8_8 import Bus
    >>> import copy
    >>> bus1 = Bus(['Alice', 'Bill', 'Claire', 'David'])
    >>> bus2 = copy.copy(bus1)
    >>> bus3 = copy.deepcopy(bus1)

    我们让Alice从bus1下车:

    >>> bus1.drop('Alice')

    然后在查看bus2和bus3的乘客:

    >>> bus2.passengers
    ['Bill', 'Claire', 'David']
    >>> bus3.passengers
    ['Alice', 'Bill', 'Claire', 'David']

    查看对象内存图我们可以明白其中的原理,

    Alice下车前,对象内存图如下:

    Alice下车后对象内存图如下:

  • 相关阅读:
    SQL所有者更改问题
    人生路上对我影响最大的三位老师
    自我介绍
    Ural_1146. Maximum Sum (DP)
    Ural_1654. Cipher Message(栈)
    Ural_1333. Genie Bomber 2
    POJ_2112 Optimal Milking(网络流)
    Ural_1031.Railway Ticket (DP)
    Ural_1030. Titanic
    Ural_1207. Median on the Plane(计算几何)
  • 原文地址:https://www.cnblogs.com/z-joshua/p/7798568.html
Copyright © 2020-2023  润新知