Python 的赋值,浅拷贝和深拷贝详解

Python 的赋值、浅拷贝和深拷贝详解

赋值、浅拷贝和深拷贝是 Python 中经常涉及的概念,也是容易混淆的概念。本文将详细讲解这三个概念的定义、区别和示例说明。

赋值

赋值是将一个对象的引用复制给另一个变量,让它指向同一个对象。例如:

a = [1, 2, 3]
b = a

前面的语句将 [1, 2, 3] 这个列表对象赋值给了 a 变量,而 b 变量则将 a 变量的引用复制一份成为自己的引用。这时候 ab 两个变量都指向同一个列表对象。修改 ab 变量所指向的列表,另一个变量所指向的列表也会发生相应的变化。

a[0] = 0
print(a)  # [0, 2, 3]
print(b)  # [0, 2, 3]

浅拷贝

浅拷贝是创建一个新的对象,但是新对象作为容器只包括原对象的引用。例如:

import copy

a = [1, 2, [3, 4]]
b = copy.copy(a)

与赋值不同的是,浅拷贝是通过对原对象的某些层次进行复制,创建一个新的对象,并将原对象中的引用复制到新对象中。在这个过程中,新对象与原对象共享内部列表这样的可变对象。当修改内部的可变对象时,两个变量所指向的列表不同,但是它们所包含的对象相同。

a[0] = 0
a[2][0] = 0
print(a)  # [0, 2, [0, 4]]
print(b)  # [1, 2, [0, 4]]

深拷贝

深拷贝是创建一个新的对象,包括原对象及其所有子对象的拷贝。例如:

import copy

a = [1, 2, [3, 4]]
b = copy.deepcopy(a)

深拷贝与浅拷贝的区别在于对于原对象的子对象,深拷贝将递归地进行子对象的复制,创建一整个新的对象,而浅拷贝仅仅是对子对象内层的引用进行复制,会影响子对象中共享的可变对象。

a[0] = 0
a[2][0] = 0
print(a)  # [0, 2, [0, 4]]
print(b)  # [1, 2, [3, 4]]

由于深拷贝是递归进行的,当对象的层次很深或者包含循环引用时,深拷贝的性能会变得很低。这时候可以考虑使用其他的方法来减少拷贝的次数。

示例说明

示例一

import copy

a = [1, 2, [3, 4]]
b = a  # 赋值
c = copy.copy(a)  # 浅拷贝
d = copy.deepcopy(a)  # 深拷贝

a[0] = 0
a[2][0] = 0

print(a)  # [0, 2, [0, 4]]
print(b)  # [0, 2, [0, 4]]
print(c)  # [1, 2, [0, 4]]
print(d)  # [1, 2, [3, 4]]

在这个示例中,我们创建了一个嵌套列表的对象,并通过赋值、浅拷贝和深拷贝分别创建了三个新的变量。我们修改了 a 变量所指向的列表对象的元素值,即 [1, 2, [3, 4]] -> [0, 2, [0, 4]]。并且,我们也修改了 a 变量所指向的列表对象中的嵌套列表对象的元素值,即 [3, 4] -> [0, 4]。我们可以看到,赋值和浅拷贝得到的变量所指向的列表对象同样发生了变化,而深拷贝得到的变量所指向的列表对象不受影响。

示例二

import copy

a = [1, 2]
b = [3, 4]
c = [a, b]
d = [a, b]
e = copy.copy(c)
f = copy.deepcopy(c)

print(c is d)  # False
print(c == d)  # True

a[0] = 0
print(c)  # [[0, 2], [3, 4]]
print(d)  # [[1, 2], [3, 4]]
print(e)  # [[0, 2], [3, 4]]
print(f)  # [[1, 2], [3, 4]]

在这个示例中,我们创建了两个嵌套列表的对象,并将它们组成一个新的嵌套列表对象。我们使用了赋值、浅拷贝和深拷贝分别创建了三个新的嵌套列表对象。我们设置了 cd 变量分别指向同样的嵌套列表对象。我们修改了 a 变量所指向的列表对象的元素值,即 [1, 2] -> [0, 2]。我们用 is 判断了 cd 变量是否指向同样的列表对象,结果为 False。我们可以看到,浅拷贝得到的变量所指向的嵌套列表对象虽然不受 内部可变对象 的影响,但是共享同样的父对象;而深拷贝得到的变量所指向的嵌套列表对象完全独立,不受任何对象的影响。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python 的赋值,浅拷贝和深拷贝详解 - Python技术站

(0)
上一篇 2023年6月5日
下一篇 2023年6月5日

相关文章

  • Python实现一个简单的MySQL类

    下面是Python实现一个简单的MySQL类的详细攻略: 主要步骤 安装MySQLdb模块 在Python中操作MySQL需要使用MySQL官方提供的MySQLdb模块,因此首先需要安装MySQLdb模块。可使用以下命令进行安装: pip install MySQLdb 编写MySQL类 MySQL类是本次实现的重点,在该类中需要完成与MySQL数据库的连接…

    python 2023年5月19日
    00
  • Python 时间操作datetime详情(下)

    Python 时间操作datetime详情(下) 在《Python 时间操作datetime详情(上)》中,我们已经介绍了 date, time, datetime 对象的基本方法。在本篇文章中,我们将继续介绍 datetime 对象的进阶用法。 一、字符串和 datetime 之间的转换 datetime 对象转字符串 datetime 对象可以使用 st…

    python 2023年5月14日
    00
  • 如何用python做逐步回归

    以下是使用Python进行逐步回归的完整攻略,包括定义逐步回归、如何使用Python进行逐步回归以及两个具体的示例。 定义逐步回归 逐步回归是一种特殊的回归分析方法,用于处理多元回归分析中的变量选择问题。与其他回归分析方法不同,逐步回归算法从包含所有可能的解释变量的初始模型开始,每次只将一个解释变量添加到模型中,当该解释变量满足一定的标准(例如显著性水平)时…

    python 2023年5月14日
    00
  • 分享一个可以生成各种进制格式IP的小工具实例代码

    下面我来详细介绍一下如何分享一个可以生成各种进制格式IP的小工具实例代码。 步骤一:编写代码 首先,我们需要编写一个能够生成各种进制格式IP的小工具。这里我以Python语言为例,给出一个简单的代码示例: # 定义一个IP地址 ip = "192.168.1.1" # 转换成十进制格式 int_ip = int(”.join([bin(…

    python 2023年6月3日
    00
  • 如何编写第一个Python程序?

    下面是编写第一个Python程序的完整攻略: 步骤一:安装Python解释器 在开始编写Python程序之前,我们需要先安装Python解释器。Python官网(https://www.python.org/downloads/)提供了适用于不同操作系统的Python解释器安装包,我们可以根据自己的操作系统下载并安装。 步骤二:编写程序 安装完Python解…

    python 2023年4月19日
    00
  • Python考拉兹猜想输出序列代码实践

    Python考拉兹猜想是一个著名的数学问题,主要思想是对于任意一个正整数n,如果n是偶数,那么将n除以2;如果n是奇数,那么将n乘以3再加1。将得到的新数重复以上操作,直到最终结果为1为止。而考拉兹猜想就是猜测对于任何一个正整数n最终都可以变成1。Python可以用很简洁的代码实现该算法,具体步骤如下: 获取用户输入的正整数 def get_input():…

    python 2023年5月19日
    00
  • 详解用Python进行谷歌Search分析

    以下是使用Python进行谷歌搜索分析的完整攻略。 安装Python包 首先在命令行中使用pip安装三个包: pip install google-api-python-client google_auth google-auth-oauthlib google-auth-httplib2 创建OAuth令牌 谷歌API使用OAuth 2.0协议进行身份验证…

    python-answer 2023年3月25日
    00
  • python多核处理器算力浪费问题解决

    Python多核处理器算力浪费问题解决攻略 背景 Python 是一种解释性语言,一般情况下使用的解释器是 CPython。CPython 解释器的 GIL(全局解释器锁)机制规定在同一时刻只能有一个线程执行 Python 代码,这限制了 Python 程序在 CPU 密集型任务上的性能提升。在多核处理器上,Python 程序只使用到了一个核心,导致其他核心…

    python 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部