1. 赋值

创建一个新的变量名,指向同一个对象
在这里插入图片描述

注意:+==的区别
+= 是原地修改,原变量指向的对象不变。
= 是创建了新的对象,原变量指向新对象。

a = [1, 2]
b = a
a += [3]   # 原地修改,等价于 a.extend([3])
print(b)   # [1, 2, 3]  -> b 变了

a = a + [4] # 创建了新列表赋值给 a,b 还指向旧列表 [1,2,3]
print(b)    # [1, 2, 3]  -> b 没变

2. 浅拷贝 copy.copy()

浅拷贝只复制最外层对象,内部仍然共享引用

a = [[1, 2], [3, 4]]  
b = copy.copy(a)  
b[0].append(99)  
print(a)  # [[1, 2, 99], [3, 4]]  
b.append(5)  
print(a)  # [[1, 2, 99], [3, 4]]  
print(id(a))  
print(id(b))  
print(id(a[0]))  
print(id(b[0]))

a与b指向不一样的对象,他们的内存地址是不同的。
但浅拷贝不会拷贝内部的子对象,所以a[0]与b[0]的内存地址是相同的。

在这里插入图片描述

3. 深拷贝 copy.deepcopy()

深拷贝会递归复制所有层级,完全独立
![[Pasted image 20260421201741.png]]

a = [[1, 2], [3, 4]]  
b = copy.deepcopy(a)  
b[0].append(99)  
print(a)  # [[1, 2], [3, 4]]  
b.append(5)  
print(a)  # [[1, 2], [3, 4]]  
print(id(a))  
print(id(b))  
print(id(a[0]))  
print(id(b[0]))

深拷贝是从内存中开辟了完全不同的空间,a和b完全不同。
不管是a和b,还是a[0]和b[0],内存地址都不同。
在这里插入图片描述

4. 三者对比

操作 外层对象 内层对象 修改b.append(x)(外层) 修改b[0][0](内层)
b = a 不复制 不复制 影响 影响
copy.copy(a) 复制 不复制 不影响 影响
copy.deepcopy(a) 复制 复制 不影响 不影响

5. 更Pythonic

5.1. 一维列表

a = [1,2,3]
b = a[:]    # 切片 浅拷贝

或者

b = list(a)

注意:多维切片依然是浅拷贝

a = [[1],[2]]
b = a[:]    # 仍然是浅拷贝

5.2. 只想避免修改原数据

不需要用到deep copy,可以:

# 用不可变结构
a = tuple([1,2,3])

或者

# 函数内不修改参数
def process(data):
	return [x * 2 for x in data]
	

等价于

def process(data):
    new_list = []
    for x in data:
        new_list.append(x * 2)
    return new_list
Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐