Python 中的浅拷贝和深拷贝

在本教程中,我们将学习如何使用 Python 脚本创建浅拷贝和深拷贝。通常,我们使用=(赋值操作符)来创建 Python 对象的副本。让我们理解与用 Python 创建副本相关的完整概念。

众所周知,赋值运算符用于创建 Python 对象的副本,但这不是真的;它只创建目标和对象之间的绑定。当我们使用赋值操作符时,它不是创建一个新对象,而是创建一个共享旧对象引用的新变量。

当用户希望在不修改原始对象的情况下进行更改时,副本很有帮助。用户还喜欢创建一个副本来处理可变对象。

让我们理解下面的例子。

示例-


list1 = [[1, 2, 3], [4, 5, 6], [7, 8, 'a']]
list2 = list1

list2[1][2] = 4

print('Old List:', list1)
print('ID of Old List:', id(list1))

print('New List:', list2)
print('ID of New List:', id(list2))

输出:

Old List: [[1, 2, 3], [4, 5, 4], [7, 8, 'a']]
ID of Old List: 1909447368968
New List: [[1, 2, 3], [4, 5, 4], [7, 8, 'a']]
ID of New List: 1909447368968

解释-

在上面的输出中,我们可以看到变量 list1 和 list2 共享同一个 id 1909447368968。

如果我们对列表 1 或列表 2 中的任何值进行任何更改,更改将反映在两者中。

主要动机是创建一个 Python 对象的副本,我们可以在不改变原始数据的情况下修改副本。在 Python 中,有两种方法可以创建副本。

  • 浅拷贝
  • 深度复制

我们将使用复制模块来创建上述副本。

拷贝模块用于创建浅拷贝和深拷贝。让我们看看每种方法。

浅拷贝是存储原始元素引用的对象的拷贝。它创建新的集合对象,然后使用在原始集合中找到的子对象来占据它。

它复制嵌套对象的引用,但不创建嵌套对象的副本。所以如果我们对复制的对象做任何修改都会反映在原始对象中。我们将使用 copy() 函数来实现它。

示例-


# importing "copy" for copy operations 
import copy 

# initializing list 1 
list1 = [1, 7, [3,5], 8] 

# using copy to shallow copy 
list2 = copy.copy(list1) 

# original elements of list 
print ("The original elements before shallow copying") 
for i in range(0,len(list1)): 
   print (list1[i],end=" ") 

print("\r") 

# adding and element to new list 
list2[2][0] = 10

# checking if change is reflected 
print ("The original elements after shallow copying") 
for i in range(0,len( list1)): 
   print (list1[i],end=" ") 

输出:

The original elements before shallow copying
1 7 [3, 5] 8 
The original elements after shallow copying
1 7 [10, 5] 8

在上面的代码中,我们在列表 1 中制造了反映在另一个列表中的机会。

示例- 2


import copy

list1 = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
list2 = copy.copy(list1)

list1.append([13, 14,15])

print("Old list:", list1)
print("New list:", list2)

输出:

Old list: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]]
New list: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]

解释-

在上面的代码中,我们创建了 list1 的一个浅拷贝。新创建的列表 2 包含对存储在列表 1 中的原始嵌套对象的引用。然后,我们将[13,14,15]追加到旧列表中,并且在新列表中不复制子列表。

深度复制是我们创建一个新对象并递归添加复制元素的过程。我们将使用复制模块中的 deecopy() 方法。创建原始对象及其整个对象的独立副本。让我们理解下面的例子。

示例-


import copy
x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
z = copy.deepcopy(xs)
print(x)
prin(z)

输出:

[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

解释-

在上面的输出中,我们可以看到 z 是我们使用 deecopy() 方法创建的 x 的克隆。如果我们对其中一个子对象进行更改,不会影响原始对象。

这两个对象在深度副本中都是完全独立的。列表 x 被递归克隆,包括它的所有子对象。


import copy
x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
z = copy.deepcopy(x)

x[2][2] = 'Hello'
print(x)

示例- 2:


import copy 

list1 = [0, [1, 2], [3,5], 4] 

# using deepcopy to deep copy 
list2 = copy.deepcopy(list1) 

# original elements of list 
print ("The original list: ")
for i in range(0,len(list1)): 
   print (list1[i],end=" ") 

print("\r") 

# adding and element to new list 
list2[1][0] = 8

# Change is reflected in l2 
print ("The new list after deep copying: ")
for i in range(0,len( list1)): 
   print (list2[i],end=" ") 

print("\r") 

# Change is NOT reflected in original list 
# as it is a deep copy 
print ("The original elements:")
for i in range(0,len( list1)): 
   print (list1[i],end=" ") 

输出:

The original list: 
0 [1, 2] [3, 5] 4 
The new list after deep copying: 
0 [8, 2] [3, 5] 4 
The original elements:
0 [1, 2] [3, 5] 4

我们还可以使用复制方法复制任意 Python 对象,包括自定义类。可以使用 copy.copy() 和 copy.deepcopy() 方法复制任何对象。

让我们理解下面的例子。

示例-


import copy
class Func_New:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
      return 'Func_new(%r, %r)' % (self.x, self.y)

a = Func_New(50, 56)
b = copy.copy(a)

print(a)
print(b)

print(a is b)
print(b is a)

输出:

Func_new(50, 56)
Func_new(50, 56)
False
False

解释-

在上面的代码中,我们创建了一个名为 Func_new 的用户定义类,并定义了 repr() 来检查对象。接下来,我们使用复制模块创建了浅层副本。我们实例化该类,并检查原始的和它的浅拷贝是否都是。

复合对象是浅拷贝和深拷贝的主要区别。包含其他对象(如列表或类实例)的对象称为列表或类实例。

  • 浅拷贝会创建一个新的复合对象,然后添加对原始对象的引用。

  • 深度复制会创建一个新的复合对象,然后添加对原始对象的引用。

  • 我们可以用复制模块复制任意对象(包括自定义类)。

原创文章,作者:EBWSB,如若转载,请注明出处:https://www.506064.com/n/126647.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
EBWSBEBWSB
上一篇 2024-10-03 23:09
下一篇 2024-10-03 23:09

相关推荐

  • Python计算阳历日期对应周几

    本文介绍如何通过Python计算任意阳历日期对应周几。 一、获取日期 获取日期可以通过Python内置的模块datetime实现,示例代码如下: from datetime imp…

    编程 2025-04-29
  • Python中引入上一级目录中函数

    Python中经常需要调用其他文件夹中的模块或函数,其中一个常见的操作是引入上一级目录中的函数。在此,我们将从多个角度详细解释如何在Python中引入上一级目录的函数。 一、加入环…

    编程 2025-04-29
  • Python周杰伦代码用法介绍

    本文将从多个方面对Python周杰伦代码进行详细的阐述。 一、代码介绍 from urllib.request import urlopen from bs4 import Bea…

    编程 2025-04-29
  • 如何查看Anaconda中Python路径

    对Anaconda中Python路径即conda环境的查看进行详细的阐述。 一、使用命令行查看 1、在Windows系统中,可以使用命令提示符(cmd)或者Anaconda Pro…

    编程 2025-04-29
  • Python列表中负数的个数

    Python列表是一个有序的集合,可以存储多个不同类型的元素。而负数是指小于0的整数。在Python列表中,我们想要找到负数的个数,可以通过以下几个方面进行实现。 一、使用循环遍历…

    编程 2025-04-29
  • python强行终止程序快捷键

    本文将从多个方面对python强行终止程序快捷键进行详细阐述,并提供相应代码示例。 一、Ctrl+C快捷键 Ctrl+C快捷键是在终端中经常用来强行终止运行的程序。当你在终端中运行…

    编程 2025-04-29
  • 蝴蝶优化算法Python版

    蝴蝶优化算法是一种基于仿生学的优化算法,模仿自然界中的蝴蝶进行搜索。它可以应用于多个领域的优化问题,包括数学优化、工程问题、机器学习等。本文将从多个方面对蝴蝶优化算法Python版…

    编程 2025-04-29
  • Python程序需要编译才能执行

    Python 被广泛应用于数据分析、人工智能、科学计算等领域,它的灵活性和简单易学的性质使得越来越多的人喜欢使用 Python 进行编程。然而,在 Python 中程序执行的方式不…

    编程 2025-04-29
  • Python清华镜像下载

    Python清华镜像是一个高质量的Python开发资源镜像站,提供了Python及其相关的开发工具、框架和文档的下载服务。本文将从以下几个方面对Python清华镜像下载进行详细的阐…

    编程 2025-04-29
  • Python字典去重复工具

    使用Python语言编写字典去重复工具,可帮助用户快速去重复。 一、字典去重复工具的需求 在使用Python编写程序时,我们经常需要处理数据文件,其中包含了大量的重复数据。为了方便…

    编程 2025-04-29

发表回复

登录后才能评论