深拷贝、浅拷贝

1. 浅拷贝

浅拷贝是对于一个对象的顶层拷贝

import copy

a = [[1, 2], 3]
b = copy.copy(a)
print(id(a))
print(id(b))
print(id(a[0]))
print(id(b[0]))
print(id(a[1]))
print(id(b[1])) a[0].append(1)
print(a)
print(b)

输出结果:

2249583452872
2250135748552
2249583452808
2249583452808
140714232963984
140714232963984
[[1, 2, 1], 3]
[[1, 2, 1], 3]

copy()是浅拷贝,只拷贝了最顶层的数组,而数组中的内容只是拷贝了引用。

因此用a[0].append(1)方法后,数组a和b都发生了改变。

2. 深拷贝

深拷贝是对于一个对象所有层次的拷贝(递归)

import copy

a = [[1, 2], 3]
b = copy.deepcopy(a)
print(id(a))
print(id(b))
print(id(a[0]))
print(id(b[0])) a[0].append(1)
print(a)
print(b)

输出结果:

1931836547784
1932360400776
1931836547720
1931837818120
[[1, 2, 1], 3]
[[1, 2], 3]

deepcopy()是深拷贝,不仅拷贝最顶层的数组,数组里的内容也拷贝了,这里不同于拷贝引用,而是创建了新的地址空间,存放的内容和原数组相同。因此这次用a[0].append(1)后,b数组没有发生变化。

3.拷贝的其他方式

分片拷贝浅拷贝

import copy

a = [[1, 2], 3]
b = a[:]
print(id(a))
print(id(b))
print(id(a[0]))
print(id(b[0]))
print(id(a[1]))
print(id(b[1])) a[0].append(1)
print(a)
print(b)

输出结果:

2672287769288
2672811617864
2672287769224
2672287769224
140714232963984
140714232963984
[[1, 2, 1], 3]
[[1, 2, 1], 3]

  

可见:分片拷贝是浅拷贝。

字典的copy()方法

d = dict(name='xiaoming', friend=['xiaohong', 'xiaoying'])

c = d.copy()

print(d)
print(c) print(id(d))
print(id(c)) print(id(d['name']))
print(id(c['name'])) print(id(d['friend']))
print(id(c['friend'])) d['friend'].append('lisa') print(d)
print(c)

  

结果:

{'name': 'xiaoming', 'friend': ['xiaohong', 'xiaoying']}
{'name': 'xiaoming', 'friend': ['xiaohong', 'xiaoying']}
2175018372336
2175021103360
2175021498672
2175021498672
2175017902728
2175017902728
{'name': 'xiaoming', 'friend': ['xiaohong', 'xiaoying', 'lisa']}
{'name': 'xiaoming', 'friend': ['xiaohong', 'xiaoying', 'lisa']}

  

可见,字典的copy()方法也是浅拷贝。

4.注意

copy()和deepcopy()对于不包含可变类型数据的元组,只会拷贝引用

import copy

d = (1, 2, 3)

c = copy.copy(d)
b = copy.deepcopy(d) print(id(d))
print(id(c))
print(id(b))

结果:

1959295969464
1959295969464
1959295969464

当deepcopy()对于包含可变类型数据的元组时,才会拷贝整个元组的内容

import copy

d = (1, 2, [1,2,3])

c = copy.copy(d)
b = copy.deepcopy(d) print(id(d))
print(id(c))
print(id(b))

  

结果:

2774011472056
2774011472056
2774011384024

  

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

  1. python 深拷贝与浅拷贝

    浅拷贝的方式有: lst=[1,2,3] (1)直接赋值: lst_cp = lst (2)for循环遍历生成:lst_cp= [i for i in lst] (3)copy模块下,copy.cop ...

  2. Python深拷贝和浅拷贝

    1- Python引用计数[1] 1.1 引用计数机制 引用计数是计算机编程语言中的一种内存管理技术,是指将资源(可以是对象.内存或磁盘空间等等)的被引用次数保存起来,当被引用次数变为零时就将其释放的 ...

  3. 【python测试开发栈】—理解python深拷贝与浅拷贝的区别

    内存的浅拷贝和深拷贝是面试时经常被问到的问题,如果不能理解其本质原理,有可能会答非所问,给面试官留下不好的印象.另外,理解浅拷贝和深拷贝的原理,还可以帮助我们理解Python内存机制.这篇文章将会通过 ...

  4. Python深拷贝与浅拷贝区别

    可变类型 如list.dict等类型,改变容器内的值,容器地址不变. 不可变类型 如元组.字符串,原则上不可改变值.如果要改变对象的值,是将对象指向的地址改变了 浅拷贝 对于可变对象来说,开辟新的内存 ...

  5. Python 深拷贝和浅拷贝的区别

    python的复制,深拷贝和浅拷贝的区别    在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用  ...

  6. python深拷贝和浅拷贝的区别

    首先深拷贝和浅拷贝都是对象的拷贝,都会生成一个看起来相同的对象,他们本质的区别是拷贝出来的对象的地址是否和原对象一样,也就是地址的复制还是值的复制的区别. 什么是可变对象,什么是不可变对象: 可变对象 ...

  7. PYTHON 深拷贝,浅拷贝

    声明:本篇笔记,模仿与其它博客中的内容 浅拷贝 浅拷贝,在内存中只额外创建第一层数据 import copy n1 = {"k1": "wu", "k ...

  8. Python 深拷贝和浅拷贝

    Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果. 下面本文就通过简单的例子介绍一下这些概念之间的差别. 对象赋值 直接看一段代码: will= ...

  9. Python深拷贝和浅拷贝!

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

随机推荐

  1. php设置错误,错误记录

    //设置错误级别. error_reporting(E_ALL);  //显示所有错误 error_reporting(E_ALL&~E_NOTICE);  //显示所有错误但不显示提示级别的 ...

  2. 一些好用的 Oracle 批处理和语句

    # 备份脚本 backup.bat @ECHO OFF COLOR 0A SET DaysAgo=1 SET Today=%date:~0,4%%date:~5,2%%date:~8,2% EXP u ...

  3. 第一个Django应用程序_part3

    一.概述 此文延续第一个Django应用程序part2. 官方文档:https://docs.djangoproject.com/en/1.11/intro/tutorial03/ view是Djan ...

  4. Shiro 集成Spring 使用 redis时 使用redisTemplate替代jedisPool(五)

    1.添加依赖架包: <dependency> <groupId>org.springframework.data</groupId> <artifactId& ...

  5. p2093 [国家集训队]JZPFAR

    传送门 分析 首先给大家推荐一个非常好的KDTree笔记 here 此题就是y9ong优先队列维护距离最远的k个,最后输出队首元素即可 估价函数就是max和min两点到 询问点的最远距离 代码 #in ...

  6. dapper利用DynamicParameters构建动态参数查询

    public static int GetTotalLogin(string username,DateTime start, DateTime end) { using (var _connecti ...

  7. Matlab神经网络

    1. <MATLAB神经网络原理与实例精解> 2. B站:https://search.bilibili.com/all?keyword=matlab&from_source=na ...

  8. 编写高质量代码改善C#程序的157个建议——建议145:避免过长的方法和过长的类

    建议145:避免过长的方法和过长的类 如果违反“一个方法只做一件事”及类型的“单一职责原则”,往往会产生过长的方法和过长的类. 如果方法过长,意味着可以站在更高的层次上重构出若干更小的方法.以行数作为 ...

  9. 编写高质量代码改善C#程序的157个建议——建议143:方法抽象级别应在同一层次

    建议143:方法抽象级别应在同一层次 看下面代码: class SampleClass { public void Init() { //本地初始化代码1 //本地初始化代码2 RemoteInit( ...

  10. 编写高质量代码改善C#程序的157个建议——建议65:总是处理未捕获的异常

    建议65:总是处理未捕获的异常 处理为捕获的异常是每个应用程序具备的基本功能,C#在APPDomain提供了UnhandledException事件来接收未捕获到的异常的通知.常见的应用如下: sta ...