您的位置:

python中的深浅复制(python中深浅拷贝)

本文目录一览:

Python里面如何拷贝一个对象?(赋值,浅拷贝,深拷贝的区别)

赋值(=):就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。

浅拷贝:创建一个新的对象,但它包含的是对原始对象中包含项的引用(如果用引用的方式修改其中一个对象,另外一个也会修改改变){1,完全切片方法;2,工厂函数,如list();3,copy模块的copy()函数}

深拷贝:创建一个新的对象,并且递归的复制它所包含的对象(修改其中一个,另外一个不会改变){copy模块的deep.deepcopy()函数}

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

在Python中存在深拷贝与浅拷贝的区别,相信有些Python初学者可能就有些疑惑,是指什么意思呢?

1. 赋值其实只是传递对象引用,引用对象id是一样的。

2. 浅拷贝是指拷贝的只是原始对象元素的引用,换句话说,浅拷贝产生的对象本身是新的,但是它的内容不是新的,只是对原对象的一个引用。

3. 深拷贝是指完全拷贝原始对象,而且产生的对象是新的,并且不受其他引用对象的操作影响。

举例区分Python中的浅复制与深复制

举例区分Python中的浅复制与深复制

这篇文章主要介绍了举例区分Python中的浅复制与深复制,是Python入门学习中的重要知识,需要的朋友可以参考下

copy模块用于对象的拷贝操作。该模块非常简单,只提供了两个主要的方法: copy.copy 与 copy.deepcopy ,分别表示浅复制与深复制。什么是浅复制,什么是深复制,网上有一卡车一卡车的资料,这里不作详细介绍。复制操作只对复合对象有效。用简单的例子来分别介绍这两个方法。

浅复制只复制对象本身,没有复制该对象所引用的对象。

#coding=gbk

import copy

l1 = [1, 2, [3, 4]]

l2 = copy.copy(l1)

print l1

print l2

l2[2][0] = 50

print l1

print l2

#---- 结果 ----

[1, 2, [3, 4]]

[1, 2, [3, 4]]

[1, 2, [50, 4]]

[1, 2, [50, 4]]

同样的代码,使用深复制,结果就不一样:

import copy

l1 = [1, 2, [3, 4]]

l2 = copy.deepcopy(l1)

print l1

print l2

l2[2][0] = 50

print l1

print l2

#---- 结果 ----

[1, 2, [3, 4]]

[1, 2, [3, 4]]

[1, 2, [3, 4]]

[1, 2, [50, 4]]

改变copy的默认行为

在定义类的时候,通过定义__copy__和__deepcopy__方法,可以改变copy的默认行为。下面是一个简单的例子:

class CopyObj(object):

def __repr__(self):

return "CopyObj"

def __copy__(self):

return "Hello"

obj = CopyObj()

obj1 = copy.copy(obj)

print obj

print obj1

#---- 结果 ----

CopyObj

Hello

python 为什么有深拷贝浅拷贝

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

一、赋值(assignment)

在《Python FAQ1》一文中,对赋值已经讲的很清楚了,关键要理解变量与对象的关系。

12345

a = [1, 2, 3] b = a print(id(a), id(b), sep='\n')139701469405552139701469405552

在Python中,用一个变量给另一个变量赋值,其实就是给当前内存中的对象增加一个“标签”而已。

如上例,通过使用内置函数 id() ,可以看出 a 和 b 指向内存中同一个对象。a is b会返回 True 。

二、浅拷贝(shallow copy)

注意:浅拷贝和深拷贝的不同仅仅是对组合对象来说,所谓的组合对象就是包含了其它对象的对象,如列表,类实例。而对于数字、字符串以及其它“原子”类型,没有拷贝一说,产生的都是原对象的引用。

所谓“浅拷贝”,是指创建一个新的对象,其内容是原对象中元素的引用。(拷贝组合对象,不拷贝子对象)

常见的浅拷贝有:切片操作、工厂函数、对象的copy()方法、copy模块中的copy函数。

12345678910

a = [1, 2, 3] b = list(a) print(id(a), id(b)) # a和b身份不同140601785066200 140601784764968 for x, y in zip(a, b): # 但它们包含的子对象身份相同... print(id(x), id(y))... 140601911441984 140601911441984140601911442016 140601911442016140601911442048 140601911442048

从上面可以明显的看出来,a 浅拷贝得到 b,a 和 b 指向内存中不同的 list 对象,但它们的元素却指向相同的 int 对象。这就是浅拷贝!

三、深拷贝(deep copy)

所谓“深拷贝”,是指创建一个新的对象,然后递归的拷贝原对象所包含的子对象。深拷贝出来的对象与原对象没有任何关联。

深拷贝只有一种方式:copy模块中的deepcopy函数。

1234567891011

import copy a = [1, 2, 3] b = copy.deepcopy(a) print(id(a), id(b))140601785065840 140601785066200 for x, y in zip(a, b):... print(id(x), id(y))... 140601911441984 140601911441984140601911442016 140601911442016140601911442048 140601911442048

看了上面的例子,有人可能会疑惑:

为什么使用了深拷贝,a和b中元素的id还是一样呢?

答:这是因为对于不可变对象,当需要一个新的对象时,python可能会返回已经存在的某个类型和值都一致的对象的引用。而且这种机制并不会影响 a 和 b 的相互独立性,因为当两个元素指向同一个不可变对象时,对其中一个赋值不会影响另外一个。

我们可以用一个包含可变对象的列表来确切地展示“浅拷贝”与“深拷贝”的区别:

1234567891011121314151617181920

import copy a = [[1, 2],[5, 6], [8, 9]] b = copy.copy(a) # 浅拷贝得到b c = copy.deepcopy(a) # 深拷贝得到c print(id(a), id(b)) # a 和 b 不同139832578518984 139832578335520 for x, y in zip(a, b): # a 和 b 的子对象相同... print(id(x), id(y))... 139832578622816 139832578622816139832578622672 139832578622672139832578623104 139832578623104 print(id(a), id(c)) # a 和 c 不同139832578518984 139832578622456 for x, y in zip(a, c): # a 和 c 的子对象也不同... print(id(x), id(y))... 139832578622816 139832578621520139832578622672 139832578518912139832578623104 139832578623392

从这个例子中可以清晰地看出浅拷贝与深拷贝地区别。

总结:

1、赋值:简单地拷贝对象的引用,两个对象的id相同。

2、浅拷贝:创建一个新的组合对象,这个新对象与原对象共享内存中的子对象。

3、深拷贝:创建一个新的组合对象,同时递归地拷贝所有子对象,新的组合对象与原对象没有任何关联。虽然实际上会共享不可变的子对象,但不影响它们的相互独立性。

浅拷贝和深拷贝的不同仅仅是对组合对象来说,所谓的组合对象就是包含了其它对象的对象,如列表,类实例。而对于数字、字符串以及其它“原子”类型,没有拷贝一说,产生的都是原对象的引用。

Python中的赋值,浅拷贝和深拷贝的区别

赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。

浅拷贝:创建一个新的对象,但它包含的是对原始对象中包含项的引用(如果用引用的方式修改其中一个对象,另外一个也会修改改变){1,完全切片方法;2,工厂函数,如list();3,copy模块的copy()函数}

深拷贝:创建一个新的对象,并且递归的复制它所包含的对象(修改其中一个,另外一个不会改变){copy模块的deep.deepcopy()函数}