在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的复制及深拷贝与浅拷贝探究的更多相关文章

  1. 浅谈python 复制(深拷贝,浅拷贝)

    博客参考:点击这里 python中对象的复制以及浅拷贝,深拷贝是存在差异的,这儿我们主要以可变变量来演示,不可变变量则不存在赋值/拷贝上的问题(下文会有解释),具体差异如下文所示 1.赋值: a=[1 ...

  2. python中文件的复制

    python中文件的复制 python的os模块有很多文件目录相关的函数,但没有提供直接复制文件的函数,当然可以通过边都边写的方式复制文件.想要直接复制文件可以通过shutil模块 shutil模块是 ...

  3. Python中复制、深拷贝和浅拷贝的区别

    深拷贝定义(deepcopy) 在Python中,由于一切皆对象,所以任何变量都可以被引用,也即可以被赋值给任何变量.但是在Python中,给变量赋值,是区分的,一般情况下,Python中的变量赋值都 ...

  4. [Python]Python中的浅复制与深复制

    看python的文档,发现list有copy方法,描述说效果同a[:]. 感觉有点惊讶,之前一直以为a[:]执行的是深复制. test了一下,发现确实如果a中存在可变对象,如list/set/dict ...

  5. python的复制,深拷贝和浅拷贝的区别

    在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一般有三种方法, alist=[1,2,3,[& ...

  6. python的复制,深拷贝和浅拷贝的区别(转)

    在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一般有三种方法, alist=[1,2,3,[& ...

  7. 【转】python的复制,深拷贝和浅拷贝的区别

    在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一般有三种方法, alist=[1,2,3,[& ...

  8. JAVA中对象的克隆及深拷贝和浅拷贝

    使用场景: 在日常的编程过程 中,经常会遇到,有一个对象OA,在某一时间点OA中已经包含了一些有效值 ,此时可能会需一个和OA完全相对的新对象OB,并且要在后面的操作中对OB的任何改动都不会影响到OA ...

  9. Python中的赋值(复制)、浅拷贝、深拷贝之间的区别

    1.赋值: 只是复制了新对象的引用,不会开辟新的内存空间.  2.浅拷贝: 创建新对象,其内容是原对象的引用.    浅拷贝有三种形式:切片操作,工厂函数,copy模块中的copy函数.    如: ...

随机推荐

  1. spring MVC--配置注解

    <context-param> 作用:该元素用来声明应用范围(整个WEB项目)内的上下文初始化参数 param-name 设定上下文的参数名称.必须是唯一名称 param-value 设定 ...

  2. 2018.5.8 Project review

    1 .product introduced A. Function requirement (customer) The product function is control the 1KW and ...

  3. [: xxxx: Unexpected operator

    /*************************************************************************** * [: xxxx: Unexpected o ...

  4. EasyDarwin+ffmpeg进行PC(摄像头+麦克风)流媒体直播服务

    上一回我们描述了用EasyDarwin+ffmpeg进行摄像机直播的过程:ffmpeg推送,EasyDarwin转发,vlc播放 实现整个RTSP直播 我们再进行一个方面的描述,那就是pc摄像头+麦克 ...

  5. ACM学习历程—HDU5637 Transform(数论 && 最短路)

    题目链接:http://codeforces.com/problemset/problem/590/A 题目大意是给两种操作,然后给你一个s,一个t,求s至少需要多少次操作到t. 考虑到第一种操作是将 ...

  6. NOIp2018集训test-10-17 (bike day3)

    发现自己gradully get moodier and moodier了 负面情绪爆发地越来越频繁,根本out of control,莫名其妙地就像着了魔一样 为什么用英语大概是因为今天早上早自习因 ...

  7. 搭建DNS服务器-bind

    1. 安装 yum install -y bind-chroot yum install -y bind-utils service named-chroot start    2. 修改配置 增加一 ...

  8. android开发中 解决服务器端解析MySql数据时中文显示乱码的情况

    首先,还是确认自己MySql账户和密码 1.示例  账户:root   密码:123456   有三个字段   分别是_id  .username(插入有中文数据).password 1)首先我们知道 ...

  9. Python:字典的pop()方法

    pop():移除序列中的一个元素(默认最后一个元素),并且返回该元素的值. 一)移除list的元素,若元素序号超出list,报错:pop index out of range(超出范围的流行指数): ...

  10. Python知识点: os.popen

    用例:f = os.popen("%s %s %s" % ("pkg-config", " ".join(args), mod)) pope ...