在Python中,经常要对一个list进行复制。对于复制,自然的就有深拷贝与浅拷贝问题。深拷贝与浅拷贝的区别在于,当从原本的list复制出的list之后,修改其中的任意一个是否会对另一个造成影响,即这两个list在内存中是否储存在同一个区域,这也是区分深拷贝与浅拷贝的重要依据。接下来我们就针对Python中list复制的几种方法,来探究一下其是属于深拷贝还是浅拷贝。弄清楚这个问题,有助于我们在编程中规避错误,减少不必要的调试时间。

一、非拷贝方法——直接赋值

  如果用=直接赋值,是非拷贝方法。这两个列表是等价的,修改其中任何一个列表都会影响到另一个列表。这也是Python作为动态语言与C这类静态语言在思想上的不同之处。

old = [1,[1,2,3],3]
new = old
print('Before:')
print(old)
print(new)
new[0] = 3
new[1][0] = 3
print('After:')
print(old)
print(new)

运行结果如下:

二、浅拷贝的几种方法

1.copy()方法

  我们来看以下代码:

old = [1,[1,2,3],3]
new = old.copy()
print('Before:')
print(old)
print(new)
new[0] = 3
new[1][0] =3
print('After:')
print(old)
print(new)

运行结果如下:

  对于list的第一层,是实现了深拷贝,但对于嵌套的list,仍然是浅拷贝。这其实很好理解,内层的list保存的是地址,复制过去的时候是把地址复制过去了。嵌套的list在内存中指向的还是同一个。

2.使用列表生成式

  使用列表生成式产生新列表也是一个浅拷贝方法,只对第一层实现深拷贝。

old = [1,[1,2,3],3]
new = [i for i in old]
print('Before')
print(old)
print(new)
new[0] = 3
new[1][0] = 3
print('After')
print(old)
print(new)

运行结果如下:

3.用for循环遍历

  通过for循环遍历,将元素一个个添加到新列表中。这也是一个浅拷贝方法,只对第一层实现深拷贝。

old = [1,[1,2,3],3]
new = []
for i in range(len(old)):
new.append(old[i])
print('Before:')
print(old)
print(new)
new[0] = 3
new[1][0] = 3
print('After:')
print(old)
print(new)

运行结果如下:

4.使用切片

  通过使用[:]切片,可以浅拷贝整个列表。同样的,只对第一层实现深拷贝。

old = [1,[1,2,3],3]
new = old[:]
print('Before:')
print(old)
print(new)
new[0] = 3
new[1][0] = 3
print('After:')
print(old)
print(new)

运行结果如下:

三、深拷贝的实现

  如果用deepcopy()方法,则无论多少层,无论怎样的形式,得到的新列表都是和原来无关的,这是最安全最清爽最有效的方法。

  使用时,要导入copy。

import copy
old = [1,[1,2,3],3]
new = copy.deepcopy(old)
print('Before:')
print(old)
print(new)
new[0] = 3
new[1][0] = 3
print('After:')
print(old)
print(new)

运行结果如下:

来源:https://www.cnblogs.com/Black-rainbow/p/9577029.html

list深拷贝和浅拷贝的更多相关文章

  1. C#设计模式:原型模式(Prototype)及深拷贝、浅拷贝

    原型模式(Prototype) 定义: 原型模式:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.被复制的实例被称为原型,这个原型是可定制的. Prototype Pattern也是一 ...

  2. Objective-C中的深拷贝和浅拷贝

    在Objective-C中对象之间的拷贝分为浅拷贝和深拷贝.说白了,对非容器类的浅拷贝就是拷贝对象的地址,对象里面存的内容仍然是一份,没有新的内存被分配.对非容器类的深拷贝就是重写分配一块内存,然后把 ...

  3. $.extend()的深拷贝和浅拷贝详细讲解

    版权声明:作者原创,转载请注明出处! 语法:jQuery.extend( [deep ], target, object1 [, objectN ] ) 描述: 将两个或更多对象的内容合并到第一个对象 ...

  4. JavaScript中面向对象的的深拷贝和浅拷贝

    理解深拷贝和浅拷贝之前需要弄懂一些基础概念,内存中存储的变量类型分为值类型和引用类型. 1.值类型赋值的存储特点, 将变量内的数据全部拷贝一份, 存储给新的变量. 例如:var num = 123 : ...

  5. C++深拷贝与浅拷贝

    当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用.也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用.以下情况都会调用拷贝构造函数: (1)一个对 ...

  6. C++的深拷贝与浅拷贝

    对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面是一个类对象拷贝的简单例子. #i ...

  7. Python赋值语句与深拷贝、浅拷贝的区别

    参考:http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-d ...

  8. [C#进阶系列]专题一:深入解析深拷贝和浅拷贝

    一.前言 这个星期参加了一个面试,面试中问到深浅拷贝的区别,然后我就简单了讲述了它们的之间的区别,然后面试官又继续问,如何实现一个深拷贝呢?当时只回答回答了一种方式,就是使用反射,然后面试官提示还可以 ...

  9. 也来玩玩 javascript对象深拷贝,浅拷贝

    经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One method of copying an object is ...

  10. OC中的深拷贝与浅拷贝

    深拷贝(deep copy)与浅拷贝(shallow copy)的定义一直是有争论的. 一种理解是: 所谓的浅拷贝, 就是不完全的拷贝 NSString *s = @"123"; ...

随机推荐

  1. Codeforces 1097F. Alex and a TV Show

    传送门 由于只要考虑 $\mod 2$ 意义下的答案,所以我们只要维护一堆的 $01$ 容易想到用 $bitset$ 瞎搞...,发现当复杂度 $qv/32$ 是可以过的... 一开始容易想到对每个集 ...

  2. 怎样获取所有style节点

    通过 document.styleSheets 获取所有的样式表节点. document.styleSheets instanceof StyleSheetList; // true 注意: 1. 返 ...

  3. Faster RCNN学习笔记

    感谢知乎大神的分享 https://zhuanlan.zhihu.com/p/31426458 Ross B. Girshick在2016年提出了新的Faster RCNN,在结构上,Faster R ...

  4. WebStorm使用码云插件问题

    由于项目需求,需要在WebStorm中使用码云插件,在下载安装的过程中出现一系列的问题,现总结出现的问题和解决方法. 先说一下码云是什么?码云有什么作用? 码云的主要功能: 码云除了提供最基础的 Gi ...

  5. c#泛型约束(转载)

    博客地址:https://www.cnblogs.com/zhengwk/p/5541921.html 六种类型的约束: T:结构 类型参数必须是值类型.可以指定除 Nullable 以外的任何值类型 ...

  6. JS 实现继承的方法 ES6 and ES5

    继承 ES6 方法  (类的继承) ES6中有一个属性的 extends 语法: ​ • class Father {} ​ • class Son extends Father{} ​ 注意:是子类 ...

  7. netstat用法详解

    netstat用法详解 知识,netstat用法详解 图片 netstat用法详解 内容,netstat用法详介绍,netstat用法详正文 netstat命令是一个监控TCP/IP网络的非常有用的工 ...

  8. @media screen媒体查询实现页面自适应布局

    @media screen and (min-width:1200px){ //大于等于1200px才会进入 }   @media screen and (max-width:375px) { //小 ...

  9. C++ STL 之 内建函数对象

    STL 内建了一些函数对象.分为:算数类函数对象,关系运算类函数对象,逻辑运算类仿函数.这些仿函数所产生的对象,用法和一般函数完全相同,当然我们还可以产生无名的临时对象来履行函数功能.使用内建函数对象 ...

  10. OverflowError:django signed integer is greater than maximum 数据库日期字段相关错

    使用django中的默认数据库sqlite3, 在pycharm中录入日期字段相关信息结果出现问题 在保存的时候如图 直接在界面选择的日期变成了时间戳, 并且在获取数据的时候报错 经过查询之后(舔大佬 ...