深浅copy,何为深浅copy,深copy和浅copy两者有何不同

copy,拷贝,顾名思义,自然是把东西复制过来,呈现在眼前的是一样的,例如:

a = [1,2,3,4,5]
b = a
b.append(6)
print(a,b)

输出:

[1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6]

很明显,a和b的值是一样的。因为对于赋值运算来讲,a与b指向的是同一内存地址,所以他们完全是一样的

浅copy:

a = [1,2,3,4,[5]]
b = copy.copy(a)
b[4].append(6)
print(a)
print(b)

print(id(a))
print(id(b))

print(id(a[0]))
print(id(b[0]))

print(id(a[4]))
print(id(b[4]))

输出:

[1, 2, 3, 4, [5, 6]]
[1, 2, 3, 4, [5, 6]]
3123924048968
3123924049032
140709039403264
140709039403264
3123924285128
3123924285128

可以看到,a和b的输出地址不一样,原因是对于浅copy来说,只是在内存中重新创建了开辟了一个空间存放一个新列表,但是新列表中的元素与原列表中的元素是公用的,且元素原地址一样不变。

但我们如果对它进行增删改,两者是否会相互改变呢?

从上面看,列表当中的可变数据类型进行增加元素时,两者是会相互影响的,且地址一直一致;

但从下面看,对列表当中的不可变数据类型进行修改时,虽然元素地址一样,但两者是不会相互影响,并且经过修改后,元素地址发生改变,两者地址变得不一样。

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

输出:

[1, 2, 3, 4, [5]]
[0, 2, 3, 4, [5]]
140709362168064
140709362168032

而在整个列表添加新的元素时,两者同样不会相互影响,只要copy过来的元素不发生改变,元素地址会一直保持一致

import copy
a = [1,2,3,4,[5]]
b = copy.copy(a)
b.append(8)

print(a)
print(b)

print(id(a[0]))
print(id(b[0]))

输出:

[1, 2, 3, 4, [5]]
[1, 2, 3, 4, [5], 8]
140709362168064
140709362168064

所以得出结论是,浅copy时,内存会开辟一个新的空间存放一个新的列表,所以地址不一致。列表中的元素和元素地址都会被copy过来,而可变数据类型(列表中的列表,二级列表)被当作一个整体不被拷贝,所以地址永远一致,对可变数据类型中的元素改变时,a和b会相互影响,元素永远相同。

而一级列表中的不可变数据类型,虽然元素与地址都被复制过来,但两者进行修改时不会相互影响,并且修改后地址会变得不一致。而在一级列表添加新的元素时,两者同样不会相互影响,只要不改变copy过来的元素,地址会一直与copy过来的一致。

深copy:

import copy
a = [1,2,3,4,[5]]
b = copy.deepcopy(a)
b[4].append(6)
print(a)
print(b)

print(id(a))
print(id(b))

print(id(a[0]))
print(id(b[0]))

print(id(a[4]))
print(id(b[4]))

输出:

[1, 2, 3, 4, [5]]
[1, 2, 3, 4, [5, 6]]
1861657304264
1861657304328
140709043532032
140709043532032
1861657540168
1861657304456

它是拷贝所有内容。包括内部(列表的列表)的所有,形成一个新的对象,虽然与之前的值和内容一模一样,但是它们时完完全全的两个对象,所以不仅a和b的地址不同,可变数据类型的地址同样被拿出来存在新的内存当中,地址同样会不一样,所以做出改变时不会相互影响;其它与浅copy一致,不可变数据类型改变时不会相互影响,且改变后地址会发生改变;

注:

当切片进行赋值时,两者地址会不一样,并且进行增删改时,两者互不影响:

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

输出:

[1, 2, 3, 4, 5]
[2, 3, 4, 5]
2525473650376
2525473414152

仅存在一种情况,两者相互影响且地址永远一致:

a = [1,2,3,4,5]
b = a
b.append(6)
a.pop(2)
print(a)
print(b)
print(id(a))
print(id(b))

输出:

[1, 2, 4, 5, 6]
[1, 2, 4, 5, 6]
2957431125704
2957431125704

以上测试基于python3.7.4

原文地址:https://www.cnblogs.com/aizhinong/p/11336879.html

时间: 2024-10-29 22:38:17

深浅copy,何为深浅copy,深copy和浅copy两者有何不同的相关文章

python基础之赋值/深copy/浅copy

首先,不管是赋值还是深浅copy,都是针对那些可能会产生变化的值进行区分的,也就是对于数字,字符串来说,区分赋值,深浅copy是毫无意义的. 那么,让我们来对那些可变的像list set dict tuple……来进行探讨. 赋值: 有两种修改n的方法: 1  直接对n赋值 >>> n=[1,2] >>> g=n >>> id(n) 140529062430792 >>> id(g) 140529062430792 >>&

(五)聊一聊深Copy与浅Copy

一.关于浅copy与深copy 首先说明一下: 在python中,赋值其实就是对象的引用,变量就是对象的一个标签,如果把内存对象比喻成一个个房间,那么变量就是门牌号. 深copy与浅copy只是针对可变类型而言,对于不可变类型,无论深浅,值相等,内存地址一样,一旦值发生变化,相当于再创建一个对象. 浅copy有3种方法: a=[1,2,3,["a","b"],22] a1=a[:]  切片操作 a2=list(a)  工厂函数 a3=copy.copy(a)  或

python3 完全理解赋值,浅copy,深copy 通过地址详细理解~

额...老规矩,先来一天NLP再说,也没几条了. 十,在任何一个系统里,最灵活的部分是最能影响大局的部分 灵活便是有一个以上的选择,选择便是能力,因此最灵活的人便是最有能力的人. 灵活来自减少只相信自己的一套信念,价值和规条,而多凭借观察运用环境所提供的其他条件. 灵活是使事情更快有效的的重要因素,因此,亦是人生成功快乐的重要因素. 灵活亦是自信的表现,自信越不足,坚持某个模式的态度会越强硬. 容许不同的意见和可能性,便是灵活. 在一个群体中,固执使人紧张,灵活使人放松. 灵活不代表放弃自己的立

python学习笔记-(六)深copy&浅copy

在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用. 1. 赋值 赋值其实只是传递对象引用,引用对象id是一样的.原始列表改变,被赋值的b也会做相同的改变. 1 2 3 4 5 6 7 8 9 10 11 12 13 >>> alist = [1,2,3,["a","b"]] >>> b = alist >>> p

OC 中 的copy 功能 深复制 和 浅复制 的 区别

系统的类要是实现copy拷贝的功能,必须先签订拷贝NSCopying的协议,然后实现对应的方法 在.h文件中得@interface Boy : NSObject 的后面需要签订拷贝NSCopying的协议 例子: 在.h文件中 @interface Boy : NSObject<NSCopying> 1. Boy类使用copy的方法 例子: Boy *boy =[Boy boyWithName:@"zhangyangyang" hobby:@"wan"]

python 深复制与浅复制------copy模块

模块解读: 浅复制: x = copy.copy(y)深复制: x = copy.deepcopy(y)(注:模块特有的异常,copy.Error) 深copy与浅copy的差别主要体现在当有混合对象时,即在一个对象中包含其他子对象,比如在一个字典中的一个value是一个列表,这时:浅copy,没有拷贝子对象,所以原始数据改变,子对象会跟着改变.深copy,包含拷贝对象中对子对象的拷贝,也就是说原始数据改变,子对象不会随之改变. 举个例子:info = { 'name':'webber', 'j

【C/C++学院】(6)构造函数/析构函数/拷贝构造函数/深copy浅copy

1.构造函数 类的初始化即为构造函数.也为:隐式的初始化. 构造函数在对象初始化的时候,自动被调用.隐式的调用. 构造函数分为三种:有参构造函数.无参构造函数.拷贝构造函数. 有参构造函数调用有三种:括号法.等号法.手工法. #include <iostream> using namespace std; class Test { private: int m_a; public: Test()//无参构造函数 { } Test(const Test &obj)//拷贝构造函数 { }

理解一下python中的浅copy和深copy

最近在学习过程中,了解了一下,浅copy和深copy,做个记录. 所谓浅拷贝就是对引用的拷贝,所谓深拷贝就是对对象的资源的拷贝. 首先,对赋值操作我们要有以下认识: 赋值是将一个对象的地址赋值给一个变量,让变量指向该地址( 旧瓶装旧酒 ). 修改不可变对象(str.tuple)需要开辟新的空间 修改可变对象(list等)不需要开辟新的空间 浅拷贝仅仅复制了容器中元素的地址 >>> user = ['tom', ['age', 20]] >>> user_new = us

列表的使用2,深COPY和浅COPY,循环列表,步长切片

name2=names.copy() 下面我看几种奇怪的现象: 首先把源列表copy以后,把源列表第2个数值修改.那么没毛病. 如果源列表里,还包含了一个子列表:这也没毛病 如果我们这个时候修改子列表的数值.我们来看一个神奇的现象: copy是一种浅COPY,它只会COPY第一层的数据,而不会深入COPY.只会COPY子列表的内存指针,内存地址. 如果你不用COPY的方法,那问题会更严重: 结果是这样的,连浅COPY都不如:相当于只把列表的内存地址复制了一下: 简单来说就是这种情况. 但是如果是