码迷,mamicode.com
首页 > 编程语言 > 详细

Python 深浅复制

时间:2017-11-07 14:25:01      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:影响   blog   lis   元素操作   序列   pre   ini   logs   color   

(一)浅复制

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

>>> 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下车后对象内存图如下:

技术分享

Python 深浅复制

标签:影响   blog   lis   元素操作   序列   pre   ini   logs   color   

原文地址:http://www.cnblogs.com/z-joshua/p/7798568.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!