python中对象的直接赋值、浅复制和深复制

在 Python 中,直接赋值、浅复制和深复制是处理对象和数据结构(如列表、字典等)时的三种基本方式。理解它们的区别对于避免数据篡改和保持数据完整性非常重要。
注意这里说的这几种操作只针对对象和数据结构,而非比如单个数值的非对象数据。
以下是它们的详细讲解:

1. 直接赋值(Direct Assignment)

机制

  • 引用相同对象:直接赋值不会创建新对象,而是让新变量指向原始对象的内存地址。两个变量实际引用了同一个对象。
  • 内存共享:修改任意一个变量会影响到另一个变量,因为它们共享相同的内存位置。

示例

x = [1, 2, 3]
y = x  # 直接赋值
y[0] = 100

print(x)  # 输出 [100, 2, 3]
print(y)  # 输出 [100, 2, 3]

在这个例子中,xy 指向相同的列表对象,因此修改 y 也会修改 x

应用场景

  • 适用于需要两个变量同时引用同一个对象的场景。
  • 快速共享数据而不需额外开销。

2. 浅复制(Shallow Copy)

机制

  • 复制外层对象:浅复制创建一个新的对象,但只复制了原始对象的外层结构。对于嵌套对象(如列表中的列表),它只复制引用,而不是递归复制内部对象。
  • 部分独立:新对象的顶层结构独立,但嵌套结构仍然共享。

示例

使用 .copy()copy.copy()(针对通用对象)

import copy

x = [[1, 2, 3], [4, 5, 6]]
y = x.copy()  # 浅复制
y[0][0] = 100

print(x)  # 输出 [[100, 2, 3], [4, 5, 6]]
print(y)  # 输出 [[100, 2, 3], [4, 5, 6]]

在这个例子中,xy 是不同的外层列表,但共享了内部的列表。因此,修改内部列表的元素会影响两个列表。

图示

x (outer list)
|
|---> [ [1, 2, 3], [4, 5, 6] ] (inner lists)
                |                 |
                |                 |
                V                 V
         same as              same as
                |                 |
                |                 |
y (outer list)
|
|---> [ [1, 2, 3], [4, 5, 6] ] (inner lists)

应用场景

  • 适用于修改顶层结构的同时保持嵌套对象共享的场景。
  • 有效降低内存开销,但要小心嵌套对象的副作用。

3. 深复制(Deep Copy)

机制

  • 递归复制:深复制创建一个新的对象,同时递归复制所有嵌套对象,确保整个对象树都是独立的。
  • 完全独立:新对象完全独立于原始对象,任何级别的更改都不会相互影响。

示例

使用 copy.deepcopy()

import copy

x = [[1, 2, 3], [4, 5, 6]]
y = copy.deepcopy(x)  # 深复制
y[0][0] = 100

print(x)  # 输出 [[1, 2, 3], [4, 5, 6]]
print(y)  # 输出 [[100, 2, 3], [4, 5, 6]]

在这个例子中,xy 是完全独立的对象,修改 y 不会影响 x

图示

x (outer list)
|
|---> [ [1, 2, 3], [4, 5, 6] ] (inner lists)

y (outer list)
|
|---> [ [100, 2, 3], [4, 5, 6] ] (inner lists)

应用场景

  • 适用于需要完全独立副本的场景。
  • 有助于避免嵌套结构中的副作用,但相对开销较大。

总结

概述

  • 直接赋值:共享同一对象。
  • 浅复制:复制外层对象,但嵌套对象共享。
  • 深复制:递归复制整个对象树,完全独立。

比较表

操作类型内存共享顶层结构独立嵌套对象独立内存开销应用场景
直接赋值简单引用
浅复制中等部分独立
深复制完全独立

代码示例总结

# 直接赋值
a = [1, 2, 3]
b = a
b[0] = 100

print(a)  # [100, 2, 3]
print(b)  # [100, 2, 3]

# 浅复制
import copy
c = [[1, 2], [3, 4]]
d = c.copy()
d[0][0] = 100

print(c)  # [[100, 2], [3, 4]]
print(d)  # [[100, 2], [3, 4]]

# 深复制
e = [[1, 2], [3, 4]]
f = copy.deepcopy(e)
f[0][0] = 100

print(e)  # [[1, 2], [3, 4]]
print(f)  # [[100, 2], [3, 4]]

这样就清晰地展示了直接赋值、浅复制和深复制的区别以及如何选择使用它们。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值