2024-07-18 11:30阅读: 19评论: 0推荐: 0

python笔记:赋值,浅拷贝和深拷贝

在 Python 中,变量赋值、浅拷贝和深拷贝在处理对象时有不同的行为和应用场景。以下是它们的详细区别:

1. 赋值

赋值操作只是创建了一个新的引用(别名)来指向同一个对象。也就是说,赋值操作并不创建新的对象,原始对象和赋值后的变量指向同一块内存区域。

a = [1, 2, 3]
b = a # b 是 a 的引用
b[0] = 99
print("a:", a) # 输出: [99, 2, 3]
print("b:", b) # 输出: [99, 2, 3]

如上所示,修改 b 的内容也会影响到 a,因为它们指向同一个对象。

2. 浅拷贝

浅拷贝创建了一个新的对象,但并不递归地复制子对象。新的对象包含了对原始对象中子对象的引用,因此修改新对象的子对象也会影响到原始对象。

import copy
a = [1, 2, [3, 4]]
b = copy.copy(a) # 创建 a 的浅拷贝
b[2][0] = 99
print("a:", a) # 输出: [1, 2, [99, 4]]
print("b:", b) # 输出: [1, 2, [99, 4]]

如上所示,修改 b 的子对象也会影响到 a,因为浅拷贝只是复制了对子对象的引用。

3. 深拷贝

深拷贝创建了一个新的对象,并且递归地复制所有的子对象。新对象和原始对象完全独立,修改新对象不会影响到原始对象。

import copy
a = [1, 2, [3, 4]]
b = copy.deepcopy(a) # 创建 a 的深拷贝
b[2][0] = 99
print("a:", a) # 输出: [1, 2, [3, 4]]
print("b:", b) # 输出: [1, 2, [99, 4]]

如上所示,修改 b 的子对象不会影响到 a,因为深拷贝创建了完全独立的对象。

总结

  • 赋值:创建一个新的引用,原始对象和新变量指向同一个对象。
  • 浅拷贝:创建一个新的对象,但只复制了对象的顶层,子对象仍然是原始对象的引用。
  • 深拷贝:创建一个新的对象,并递归地复制所有子对象,新对象和原始对象完全独立。

在讨论赋值、浅拷贝和深拷贝时,了解“顶层”、“层级”和“子对象”的概念很重要。这些术语有助于理解对象的结构以及不同复制方法的影响。

顶层、层级、子对象的概念

  1. 顶层 (Top-level):

    • 顶层是指对象的第一个层级,也就是对象本身。比如,一个列表对象的顶层就是这个列表本身,而不是它包含的元素。
  2. 层级 (Level):

    • 层级表示对象的嵌套深度。例如,一个列表中包含另一个列表,那么第一个列表是第一个层级,第二个列表是第二个层级。
  3. 子对象 (Sub-object):

    • 子对象是指包含在另一个对象中的对象。例如,一个列表中的元素(如果这些元素也是对象)就是这个列表的子对象。

示例说明

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

在上面的例子中:

  • 顶层对象是 nested_list 这个列表。
  • 第一层级包含元素 1, 2, 和 [3, 4]
  • 元素 [3, 4] 是第二层级,它是一个子对象。

赋值、浅拷贝、深拷贝的影响

  1. 赋值:

    • 赋值不会创建新对象,两个变量指向同一个对象。
    • 修改任何层级的对象,都会影响所有引用。
    a = [1, 2, [3, 4]]
    b = a # 赋值,a 和 b 指向同一个对象
    b[2][0] = 99 # 修改子对象
    print(a) # 输出: [1, 2, [99, 4]]
    print(b) # 输出: [1, 2, [99, 4]]
  2. 浅拷贝:

    • 浅拷贝创建一个新的顶层对象,但子对象仍然是引用原来的对象。
    • 修改顶层对象不影响原对象,但修改子对象会影响原对象。
    import copy
    a = [1, 2, [3, 4]]
    b = copy.copy(a) # 浅拷贝
    b[0] = 99 # 修改顶层对象
    print(a) # 输出: [1, 2, [3, 4]]
    print(b) # 输出: [99, 2, [3, 4]]
    b[2][0] = 99 # 修改子对象
    print(a) # 输出: [1, 2, [99, 4]]
    print(b) # 输出: [99, 2, [99, 4]]
  3. 深拷贝:

    • 深拷贝创建一个新的顶层对象,并递归地复制所有子对象,生成一个完全独立的对象。
    • 修改任何层级的对象都不会影响原对象。
    import copy
    a = [1, 2, [3, 4]]
    b = copy.deepcopy(a) # 深拷贝
    b[0] = 99 # 修改顶层对象
    print(a) # 输出: [1, 2, [3, 4]]
    print(b) # 输出: [99, 2, [3, 4]]
    b[2][0] = 99 # 修改子对象
    print(a) # 输出: [1, 2, [3, 4]]
    print(b) # 输出: [99, 2, [99, 4]]

何时使用

  • 赋值: 当你不需要独立的副本,只需要多个引用来操作同一个对象时。
  • 浅拷贝: 当你需要一个顶层对象的副本,但允许子对象共享时。
  • 深拷贝: 当你需要一个完全独立的对象,包括所有层级的子对象都不共享时。

理解这些概念和它们的影响有助于选择适当的复制方法,以满足特定的编程需求。

本文作者:清澈的澈

本文链接:https://www.cnblogs.com/lmc7/p/18309163

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   清澈的澈  阅读(19)  评论(0编辑  收藏  举报
历史上的今天:
2020-07-18 maven报错:不再支持源选项 5。请使用 6 或更高版本
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示