Python中list的复制及深拷贝与浅拷贝探究
在Python中,经常要对一个list进行复制。对于复制,自然的就有深拷贝与浅拷贝问题。深拷贝与浅拷贝的区别在于,当从原本的list复制出新的list之后,修改其中的任意一个是否会对另一个造成影响,即这两个list在内存中是否储存在同一个区域,这也是区分深拷贝与浅拷贝的重要依据。接下来我们就针对Python中list复制的几种方法,来探究一下其是属于深拷贝还是浅拷贝。弄清楚这个问题,有助于我们在编程中规避错误,减少不必要的调试时间。
一、非拷贝方法——直接赋值
如果用=直接赋值,是非拷贝方法。这两个列表是等价的,修改其中任何一个列表都会影响到另一个列表。这也是Python作为动态语言与C这类静态语言在思想上的不同之处。
#!/usr/bin/env python3
# -*- coding: utf-8 -*- 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()方法
我们来看以下代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*- 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.使用列表生成式
使用列表生成式产生新列表也是一个浅拷贝方法,只对第一层实现深拷贝。
#!/usr/bin/env python3
# -*- coding: utf-8 -*- 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循环遍历,将元素一个个添加到新列表中。这也是一个浅拷贝方法,只对第一层实现深拷贝。
#!/usr/bin/env python3
# -*- coding: utf-8 -*- 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.使用切片
通过使用[:]切片,可以浅拷贝整个列表。同样的,只对第一层实现深拷贝。
#!/usr/bin/env python3
# -*- coding: utf-8 -*- 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。
#!/usr/bin/env python3
# -*- coding: utf-8 -*- 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)
运行结果:
以上,就是对list的复制及深拷贝与浅拷贝探究。鉴于本人水平有限,文中有不妥之处,还请在评论中指出。
Python中list的复制及深拷贝与浅拷贝探究的更多相关文章
- 浅谈python 复制(深拷贝,浅拷贝)
博客参考:点击这里 python中对象的复制以及浅拷贝,深拷贝是存在差异的,这儿我们主要以可变变量来演示,不可变变量则不存在赋值/拷贝上的问题(下文会有解释),具体差异如下文所示 1.赋值: a=[1 ...
- python中文件的复制
python中文件的复制 python的os模块有很多文件目录相关的函数,但没有提供直接复制文件的函数,当然可以通过边都边写的方式复制文件.想要直接复制文件可以通过shutil模块 shutil模块是 ...
- Python中复制、深拷贝和浅拷贝的区别
深拷贝定义(deepcopy) 在Python中,由于一切皆对象,所以任何变量都可以被引用,也即可以被赋值给任何变量.但是在Python中,给变量赋值,是区分的,一般情况下,Python中的变量赋值都 ...
- [Python]Python中的浅复制与深复制
看python的文档,发现list有copy方法,描述说效果同a[:]. 感觉有点惊讶,之前一直以为a[:]执行的是深复制. test了一下,发现确实如果a中存在可变对象,如list/set/dict ...
- python的复制,深拷贝和浅拷贝的区别
在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一般有三种方法, alist=[1,2,3,[& ...
- python的复制,深拷贝和浅拷贝的区别(转)
在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一般有三种方法, alist=[1,2,3,[& ...
- 【转】python的复制,深拷贝和浅拷贝的区别
在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一般有三种方法, alist=[1,2,3,[& ...
- JAVA中对象的克隆及深拷贝和浅拷贝
使用场景: 在日常的编程过程 中,经常会遇到,有一个对象OA,在某一时间点OA中已经包含了一些有效值 ,此时可能会需一个和OA完全相对的新对象OB,并且要在后面的操作中对OB的任何改动都不会影响到OA ...
- Python中的赋值(复制)、浅拷贝、深拷贝之间的区别
1.赋值: 只是复制了新对象的引用,不会开辟新的内存空间. 2.浅拷贝: 创建新对象,其内容是原对象的引用. 浅拷贝有三种形式:切片操作,工厂函数,copy模块中的copy函数. 如: ...
随机推荐
- 数据库中的id不会自动 替换,这个应该处理吗。怎么处理,那个是唯一主键
- NodeJS中 Path 模块
var path = require('path'); // 当发现有多个连续的斜杠时,会替换成一个: 当路径末尾包含斜杠时,会保留: // 在 Windows 系统会使用反斜杠. var p = p ...
- diea破解
选择菜单Help->Register->License server,填上http://idea.iteblog.com/key.php,如图所示: 点击Activate,然后就搞定了.
- bzoj 2342: 双倍回文 回文自动机
题目大意: 定义双倍回文串的左一半和右一半均是回文串的长度为4的倍数的回文串 求一个给定字符串中最长的双倍回文串的长度 题解: 我们知道可以简单地判定以某一点结尾的最长回文串 我们知道可以简单地判定以 ...
- Operating System-Process(2)进程表&&中断处理
上一篇文章阐述了进程的基本信息,本文主要介绍进程的实现,主要内容: 进程表(Process Table or Process Control Blocks) 中断处理(Interrupt) 一.进程表 ...
- BZOJ1113:[POI2008]PLA
浅谈栈:https://www.cnblogs.com/AKMer/p/10278222.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php?id ...
- BZOJ3307:雨天的尾巴
浅谈线段树合并:https://www.cnblogs.com/AKMer/p/10251001.html 题目传送门:https://lydsy.com/JudgeOnline/problem.ph ...
- js函数篇
1.闭包函数,作用:不污染全局变量, 定义:与外界隔离的独立作用域被称为闭包,使用函数实现该功能称为函数闭包: 写法: (function(){ function sayHello(){ conso ...
- 接口Comparator和Comparable的区别和联系
1. Comparator 和 Comparable 相同的地方 他们都是java的一个接口, 并且是用来对自定义的class比较大小的. 什么是自定义class: 如 public class Pe ...
- Asp.net Core学习笔记
之前记在github上的,现在搬运过来 变化还是很大的,感觉和Nodejs有点类似,比如中间件的使用 ,努力学习ing... 优点 不依赖IIS 开源和跨平台 中间件支持 性能优化 无所不在的依赖注入 ...