阐述引用、浅拷贝和深拷贝前,首先需要要了解 Python 的世界里,一切皆对象,每个对象各包含一个 idendity、type 和 value。

引用(Reference)

>>> b = [1 , 2]
>>> a = [b, 3, 4]
>>>
>>> c = a
>>> print c
[[1, 2], 3, 4]
>>> id(a)
4408148552
>>> id(c)
4408148552

c = a 表示 c 和 a 指向相同的地址空间,并没有创建新的对象。

浅拷贝(Shallow copy)

常见的浅拷贝的方法,是使用数据类型本身的构造器(list, tuple, dict, set),对于可变的序列(list, tuple),我们还可以通过切片操作符':'完成浅拷贝

当然,Python 中也提供了相对应的函数 copy.copy(),适用于任何数据类型。

>>> import copy
>>> d = copy.copy(a)
>>> print d
[[1, 2], 3, 4]
>>>
>>> id(a)
4408148552
>>> id(d)
4408199792
>>>
>>> id(a[0])
4408022944
>>> id(d[0])
4408022944
>>>
>>> d[0][0] = 5
>>> print a
>>> [[5, 2], 3, 4]

d = copy.copy(a) 创建了一个新对象,复制了原有对象的引用。

深拷贝(Deep copy)

是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。

>>> e = copy.deepcopy(a)
>>> print e
>>> [[1, 2], 3, 4]
>>>
>>> id(a)
>>> 4408148552
>>> id(e)
>>> 4408394792
>>>
>>> id(a[0])
>>> 4408022944
>>> id(e[0])
>>> 4408398432
>>>
>>> e[0][0] = 5
>>> print a
>>> [[1, 2], 3, 4]

e = copy.deepcopy(a) 新建了一个新对象,完整的在内存中复制原有对象。

Note

关于浅拷贝和深拷贝的区别,Python 的 document 是这样解释的:

The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances):

  • A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.
  • A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

使用深拷贝时,需要注意以下两个问题:

  • 递归对象拷贝: Recursive objects (compound objects that, directly or indirectly, contain a reference to themselves) may cause a recursive loop.
  • 大对象拷贝: Because deep copy copies everything it may copy too much, e.g., administrative data structures that should be shared even between copies.

思考题

深度拷贝一个无限嵌套的列表。那么。当我们用等于操作符'=='进行比较时,输出会是什么呢?是 True 或者 False 还是其他?为什么呢?

import copy
x = [1]
x.append(x) y = copy.deepcopy(x) # 以下命令的输出是?
x == y

程序会报错:RecursionError: maximum recursion depth exceeded in comparison。因为x是一个无限嵌套的列表,y深度拷贝x也是一个无限嵌套的列表,理论上x==y应该返回True,但是x==y内部执行是会递归遍历列表x和y中每一个元素的值,由于x和y是无限嵌套的,因此会stack overflow,报错

参考

大部分内容参考了博客,在基础上做了补充。

python 进阶篇 浅拷贝与深拷贝的更多相关文章

  1. python进阶篇

    python进阶篇 import 导入模块 sys.path:获取指定模块搜索路径的字符串集合,可以将写好的模块放在得到的某个路径下,就可以在程序中import时正确找到. ​ import sys ...

  2. Python 引用、浅拷贝、深拷贝解析

    引用 Python是动态数据类型的语言,故在对变量进行赋值时是不用制定变量类型的. 或者说,你可以把变量赋值的过程,当作是贴一个标签,去引用该数据. 看下面的例子: In [54]: a=4 In [ ...

  3. python赋值、浅拷贝、深拷贝区别

    在写Python过程中,经常会遇到对象的拷贝,如果不理解浅拷贝和深拷贝的概念,你的代码就可能出现一些问题.所以,在这里按个人的理解谈谈它们之间的区别. 一.赋值(assignment) 在<Py ...

  4. Python 赋值、浅拷贝和深拷贝

    初学Python,和C++还是有许多不同.直接赋值.浅拷贝和深拷贝,这三种拷贝对象的操作之间还是有许多的区别.Python语言的版本为2.7,在Pycharm中进行实验. 一.直接赋值 用下面的代码来 ...

  5. Python赋值、浅拷贝、深拷贝

    一.赋值(assignment) >>> a = [1, 2, 3] >>> b = a >>> print(id(a), id(b), sep= ...

  6. javascript篇-浅拷贝与深拷贝

    理解javascript 的浅拷贝与深拷贝,首先看一下js的数据类型: js有5种基本数据类型:undefined,null,boolean,number,string 还有一种复杂的数据类型(也叫引 ...

  7. python 基础之浅拷贝与深拷贝

    浅拷贝与深拷贝 1.普通赋值 例1: a = 15b = aa = 16print(b)#例2:lst1 = [1,2,3]lst2 = lst1lst1.append(4)print(lst2)#这 ...

  8. python中的浅拷贝,深拷贝

    直接引用,间接引用 # 1.列表存储的是索引对应值的内存地址,值会单独的开辟一个内存空间 list = ["a","b"] 内存里面存储的就是list[0],l ...

  9. python进阶(6)深拷贝和浅拷贝

    深拷贝和浅拷贝 不管对于浅拷贝.还是深拷贝,针对不可变对象str.int.tuple(有点特殊).boolean,它的内存地址是不变的,拷贝的仅仅是值 import copy a = 1 b = co ...

随机推荐

  1. Magenta Demos Magenta 实战代码

    Magenta 实战代码 这个仓库包含了很多 Magenta 模型的实现.看 Magenta 库以及模型,看我们的主仓库:https://github.com/tensorflow/magenta A ...

  2. Java方法调用数组,是否改变原数组元素的总结

    Java方法调用数组,是否改变原数组元素的总结 //个人理解, 欢迎吐槽 注意String是引用型变量, 我的理解也就是指向型, 指向一个数据或变量, 画图理解最容易, string 指向的 数据的值 ...

  3. python中如何在一个for循环中遍历两个列表

    `其实就是用zip把两个列表包装起来:  for x, y in zip(list1, list2) 

  4. Vue 【前端面试题】

    前言 看看面试题,只是为了查漏补缺,看看自己那些方面还不懂.切记不要以为背了面试题,就万事大吉了,最好是理解背后的原理,这样面试的时候才能侃侃而谈.不然,稍微有水平的面试官一看就能看出,是否有真才实学 ...

  5. Go 开发环境搭建和代码调试

    写这篇笔记的目的,主要是分享我在Go学习中遇到的坑.让后面的学习者能否参考有用的经验. 其中有一些小技巧,对初学者来说,可能会大大节约填坑的时间. 比如如何设置vscode的Go调试器,Go的语法高亮 ...

  6. 1061 Dating (20分)

    Sherlock Holmes received a note with some strange strings: Let's date! 3485djDkxh4hhGE 2984akDfkkkkg ...

  7. 1047 Student List for Course (25分)

    Zhejiang University has 40,000 students and provides 2,500 courses. Now given the registered course ...

  8. Python Count函数的应用

    Python Count函数的应用 通过LeetCode Origin:https://leetcode-cn.com/problems/robot-return-to-origin/ 学会了Pyth ...

  9. Jenkins中管道案例脚本(生命式语法)

    pipeline { agent any parameters { choice( choices: 'feature\nmaster\npercent10', description: '选择要发布 ...

  10. LeetCode48, 如何让矩阵原地旋转90度

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode第29篇,我们来看一道简单的矩阵旋转问题. 题意 题目的要求很简单,给定一个二维方形矩阵,要求返回矩阵旋转90度之后的 ...