操作之灵魂——拷贝
admin
2023-07-31 01:48:41
0

原文地址

首先需要搞清楚两个概念:赋值引用,对于操作 target = source:

  1. 赋值操作:程序先新建对象target,然后将source的值拷贝到target中。这里,target和source值相同,但是它们是两个完全不同的对象。

  2. 引用操作:程序直接将target指向source,也就是说target和source是同一个对象,target只不过是source的一个别名。

python中没有赋值,只有引用。

>>> source = 12
>>> target = source
>>> target is source
True

如果我们想拷贝一个对象,而不仅仅是创建一个引用,那么该如何操作呢?万能的python提供了两种拷贝机制浅拷贝(shallow copy)、深拷贝(deep copy)供我们选择,浅拷贝和深拷贝的唯一区别在于对嵌套对象的拷贝处理上。

Function Description
copy.copy(x) Return a shallow copy of x.
copy.deepcopy(x) Return a deep copy of x.
exception copy.error Raised for module specific errors.

简单引用:浅拷贝

对于嵌套对象比如说source = [1, 2, [3, 4]],浅拷贝创建新的列表对象target,target中的所有元素均是source中元素的引用,也就是说target中的元素只是source中元素的别名。

切片操作[start:end]属于浅拷贝。

>>> source = [1, 2, [3, 4]]
>>> target = source[:]
>>> source is target
False
>>> for i in range(3):
...     print source[i] is target[i]
...
True
True
True
>>> source[2][2] = \"see here\"
>>> source, target
([1, 2, [3, \'see here\']], [1, 2, [3, \'see here\']])

图1. 浅拷贝示意图

递归拷贝:深拷贝

大多时候有浅拷贝就足够了,但是某些情况下深拷贝仍有着举足轻重的作用。

深拷贝,其实就是递归拷贝。也就是说对于嵌套对象比如说source = [1, 2, [3, 4]],深拷贝时创建新的列表对象target,然后递归地将source中的所有对象均拷贝到target中。即如果source中的元素是列表、字典等,那么python将拷贝这些列表、字典中的对象到target中去,就这样迭代下去,直到不存在嵌套结构。

>>> source = [1, 2, [3, 4]]
>>> import copy
>>> target = copy.deepcopy(source)
>>> target is source
False
>>> for i in range(3):
...     print target[i] is source[i]
...
True
True
False
>>> source[2][4] = \"see here\"
>>> source, target
([1, 2, [3, \'see here\']], [1, 2, [3, 4]])

图2. 深拷贝示意图

深拷贝存在两个问题:

  1. 对一个递归对象进行深拷贝会导致递归循环。比如values = [values, 2];

  2. 由于深拷贝要拷贝所有对象,因此有时候会拷贝多余的内容,比如管理用的数据结构应该在不同拷贝间共享。

不过_deepcopy()_函数提供了两个解决方案避免以上问题:

  1. 拷贝过程中维护一个备忘字典\”memo\”,字典中存放已经拷贝过的对象;

  2. 允许用户在自定义的类中重写拷贝操作或重写要拷贝的组件。

参考

python的赋值操作
Python Copy Through Assignment?
copy module 学习笔记

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
python清除字符串里非数字... 本文实例讲述了python清除字符串里非数字字符的方法。分享给大家供大家参考。具体如下: impor...