python中的copy模块(浅复制和深复制)
2015-08-11 20:56
141 查看
在总结copy模块中的浅复制(copy)和深复制(deepcopy)前,先对“引用”做下说明:
引用是指保存的值为对象的地址。在 Python 语言中,一个变量保存的值除了基本类型保存的是值外,其它都是引用,因此对于它们的使用就需要小心一些。下面举个例子:
问题描述:已知一个列表,求生成一个新的列表,列表元素是原列表的复制。
a=[1,2]
b=a
这种做法其实并未真正生成一个新的列表,b指向的仍然是a所指向的对象。这样,如果对a或b的元素进行修改,a,b的值同时发生变化。
a=[1,2]
b=a[:]
这样修改a对b没有影响。修改b对a没有影响。
但 这种方法只适用于简单列表,也就是列表中的元素都是基本类型,如果列表元素还存在列表的话,这种方法就不适用了。原因就是,象a[:]这种处理,只是将列 表元素的值生成一个新的列表,如果列表元素也是一个列表,如:a=[1,[2]],那么这种复制对于元素[2]的处理只是复制[2]的引用,而并未生成[2]的一个新的列表复制。为了证明这一点,测试步骤如下:
>>> a=[1,[2]]
>>> b=a[:]
>>> b
[1, [2]]
>>>a[1].append(3)
>>> a
[1, [2, 3]]
>>> b
[1, [2, 3]]
可见,对a的修改影响到了b。如果解决这一问题,可以使用copy模块中的deepcopy函数。修改测试如下:
>>> import copy
>>>a=[1,[2]]
>>>b=copy.deepcopy(a)
>>> b
[1, [2]]
>>>a[1].append(3)
>>> a
[1, [2, 3]]
>>> b
[1, [2]]
########
copy(x)潜复制
########
创建新的复合对象并通过引用复制x的成员来创建x的潜复制,它复制了对象,但对于对象中的元素,依然使用引用。对于内置类型,此函数并不经常使用。而是使用诸如list(x), dict(x), set(x)等调用方式来创建x的浅复制,要知道像这样直接使用类型名显然比使用copy()快很多。但是它们达到的效果是一样的。
判断对象之间是否是拷贝,可以用下面方法:
a is b ->True a与b引用的是同一个对象,不是拷贝;
-> False a与b是彼此拷贝对象;
引出例子来说明:
(1)
>>> a = [1,2,3]
>>> b = copy.copy(a)
>>> b
[1, 2, 3]
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3]
>>> a is b
False
(2)
>>> a = [1,2,3]
>>> b = a
>>> b
[1, 2, 3]
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>> b.append(6)
>>> a, b
([1, 2, 3, 4, 6], [1, 2, 3, 4, 6])
(3)
>>> a = [1,2,3]
>>> b = list(a)
>>> b
[1, 2, 3]
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3]
>>> (相当于b=copy(a))
(4)
>>> a = [[1], ['a'], ['A']]
>>> b = copy.copy(a)
>>> print a, b
[[1], ['a'], ['A']] [[1], ['a'], ['A']]
>>> b[1].append('b')
>>> b
[[1], ['a', 'b'], ['A']]
>>> a
[[1], ['a', 'b'], ['A']]
>>> b.append([100,101])
>>> b
[[1], ['a', 'b'], ['A'], [100, 101]]
>>> a
[[1], ['a', 'b'], ['A']]
############
deepcopy()函数
###############
完全的拷贝一个对象和一个对象的所有元素的值, 通过创建新的复合对象并重复复制x的所有成员来创建x的深复制。
eg:
>>> a = [[1], ['a'], ['A']]
>>> import copy
>>> b = copy.deepcopy(a)
>>> b
[[1], ['a'], ['A']]
>>> c = copy.copy(a)
>>> c
[[1], ['a'], ['A']]
>>> a[1].append('b')
>>> a
[[1], ['a', 'b'], ['A']]
>>> b
[[1], ['a'], ['A']]
>>> c
[[1], ['a', 'b'], ['A']]
引用是指保存的值为对象的地址。在 Python 语言中,一个变量保存的值除了基本类型保存的是值外,其它都是引用,因此对于它们的使用就需要小心一些。下面举个例子:
问题描述:已知一个列表,求生成一个新的列表,列表元素是原列表的复制。
a=[1,2]
b=a
这种做法其实并未真正生成一个新的列表,b指向的仍然是a所指向的对象。这样,如果对a或b的元素进行修改,a,b的值同时发生变化。
a=[1,2]
b=a[:]
这样修改a对b没有影响。修改b对a没有影响。
但 这种方法只适用于简单列表,也就是列表中的元素都是基本类型,如果列表元素还存在列表的话,这种方法就不适用了。原因就是,象a[:]这种处理,只是将列 表元素的值生成一个新的列表,如果列表元素也是一个列表,如:a=[1,[2]],那么这种复制对于元素[2]的处理只是复制[2]的引用,而并未生成[2]的一个新的列表复制。为了证明这一点,测试步骤如下:
>>> a=[1,[2]]
>>> b=a[:]
>>> b
[1, [2]]
>>>a[1].append(3)
>>> a
[1, [2, 3]]
>>> b
[1, [2, 3]]
可见,对a的修改影响到了b。如果解决这一问题,可以使用copy模块中的deepcopy函数。修改测试如下:
>>> import copy
>>>a=[1,[2]]
>>>b=copy.deepcopy(a)
>>> b
[1, [2]]
>>>a[1].append(3)
>>> a
[1, [2, 3]]
>>> b
[1, [2]]
########
copy(x)潜复制
########
创建新的复合对象并通过引用复制x的成员来创建x的潜复制,它复制了对象,但对于对象中的元素,依然使用引用。对于内置类型,此函数并不经常使用。而是使用诸如list(x), dict(x), set(x)等调用方式来创建x的浅复制,要知道像这样直接使用类型名显然比使用copy()快很多。但是它们达到的效果是一样的。
判断对象之间是否是拷贝,可以用下面方法:
a is b ->True a与b引用的是同一个对象,不是拷贝;
-> False a与b是彼此拷贝对象;
引出例子来说明:
(1)
>>> a = [1,2,3]
>>> b = copy.copy(a)
>>> b
[1, 2, 3]
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3]
>>> a is b
False
(2)
>>> a = [1,2,3]
>>> b = a
>>> b
[1, 2, 3]
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>> b.append(6)
>>> a, b
([1, 2, 3, 4, 6], [1, 2, 3, 4, 6])
(3)
>>> a = [1,2,3]
>>> b = list(a)
>>> b
[1, 2, 3]
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3]
>>> (相当于b=copy(a))
(4)
>>> a = [[1], ['a'], ['A']]
>>> b = copy.copy(a)
>>> print a, b
[[1], ['a'], ['A']] [[1], ['a'], ['A']]
>>> b[1].append('b')
>>> b
[[1], ['a', 'b'], ['A']]
>>> a
[[1], ['a', 'b'], ['A']]
>>> b.append([100,101])
>>> b
[[1], ['a', 'b'], ['A'], [100, 101]]
>>> a
[[1], ['a', 'b'], ['A']]
############
deepcopy()函数
###############
完全的拷贝一个对象和一个对象的所有元素的值, 通过创建新的复合对象并重复复制x的所有成员来创建x的深复制。
eg:
>>> a = [[1], ['a'], ['A']]
>>> import copy
>>> b = copy.deepcopy(a)
>>> b
[[1], ['a'], ['A']]
>>> c = copy.copy(a)
>>> c
[[1], ['a'], ['A']]
>>> a[1].append('b')
>>> a
[[1], ['a', 'b'], ['A']]
>>> b
[[1], ['a'], ['A']]
>>> c
[[1], ['a', 'b'], ['A']]
相关文章推荐
- Python使用struct处理二进制(pack和unpack用法)
- machine learning in coding(python):使用交叉验证【选择模型超参数】
- Python爬取CSDN博客专家系列——移动开发
- machine learning in coding(python):使用贪心搜索【进行特征选择】
- Python学习——struct模块的pack、unpack示例
- leetcode 日经贴,python code -Different Ways to Add Parentheses
- 《Python基础教程(第2版)》学习笔记(三):
- Python的getattr(),setattr(),delattr(),hasattr()
- sunburnt 学习笔记 (三) 连接python和solr
- 异步等待的 Python 协程
- 异步等待的 Python 协程
- python学习笔记3
- Python补充05 字符串格式化 (%操作符)
- python 详解re模块
- 从错误中学python(2)————字符串转浮点数
- python实现简单爬虫以及正则表达式简述
- Python中subprocess学习
- Python 之 sklearn 实现 PCA 降维
- python 学习点滴
- python 中文异常问题记录