(一)浅复制

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

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

最新文章

  1. [html] 有利于seo优化的div+css命名规范
  2. Lucene总体架构
  3. [转]SIP穿越NAT&FireWall解决方案
  4. resolve some fragment exception
  5. @Valid springMVC bean校验不起作用
  6. maven整合s2sh截图
  7. 自己手动写http服务器(2)
  8. jquery插件,美化select标签
  9. 继BAT之后 第四大巨头是谁
  10. SpringBoot自定义属性配置以及@ConfigurationProperties注解与@Value注解区别
  11. B树之C语言实现(包含查找、删除、插入)
  12. 《Linux内核设计与实现》 第十八章学习笔记
  13. [No0000183]Parallel Programming with .NET-How PLINQ processes an IEnumerable<T> on multiple cores
  14. python 图片
  15. Hierarchical Question-Image Co-Attention for Visual Question Answering
  16. 关于thinkphp中post提交空白的思考
  17. sql注入--基础
  18. 网站SEO优化的方法
  19. Oracle创建Rman备份专用账户
  20. Android -- PullToRefresh应用

热门文章

  1. Java中的代码块:局部代码块、构造代码块和静态代码块
  2. Windows Redis 取消保护模式C#进行访问
  3. JavaScript入门学习(2)--进度条
  4. jps命令无法找到
  5. Spark RDD理解
  6. 关于uip中的log和打印
  7. golang基础--Gocurrency并发
  8. Kafka跨网络访问设置
  9. LeetCode 910. Smallest Range II
  10. [BZOJ3678]wangxz与OJ-[Splay一类的平衡树]