在《Python编程:从入门到实践》4.4.3节中,提到了列表的复制,但并没有说的很清楚。
值拷贝、浅拷贝和深拷贝
这是三种数据拷贝的方式:
-
值拷贝:值拷贝是指将一个对象的值直接复制到另一个对象中。值拷贝通常用于基本数据类型(如 int, float, char 等),或者不可变对象(如 Python 中的 str, tuple 等)
-
浅拷贝:浅拷贝是指创建一个新的对象。如果对象中包含可变对象(如列表、字典等),则这些可变对象的引用会被复制,而不是内容本身。
-
深拷贝:深拷贝是指创建一个新的对象,并递归地复制原始对象的所有内容,包括嵌套对象。深拷贝会创建一个完全独立的新对象,修改新对象不会影响原始对象。
列表的复制
书中提到的列表复制方法a=b[:]
是一种浅拷贝,所以这里我们具体看下浅拷贝的细节。
浅拷贝创建一个新的对象,但只复制原始对象的第一层内容。对于第一层的元素:
- 如果是不可变对象(如整数、浮点数、字符串、元组等),浅拷贝会直接复制这些值。
- 如果是可变对象(如列表、字典、集合等),浅拷贝会复制这些对象的引用,而不是对象本身的内容。
用一个例子辅助理解:
a=[1,2,[1,2]]
b=a[:]
print("这是a:")
print(a)
print("这是b:")
print(b)
#处理不可变对象
print("\nb处理不可变对象")
b.append(9)
print("这是a:")
print(a)
print("这是b:")
print(b)
#处理可变对象(注意这里是引用)
print("\nb处理可变对象")
b[2].append(9)
print("这是a:")
print(a)
print("这是b:")
print(b)
输出结果
这是a:
[1, 2, [1, 2]]
这是b:
[1, 2, [1, 2]]
b处理不可变对象
这是a:
[1, 2, [1, 2]]
这是b:
[1, 2, [1, 2], 9]
b处理可变对象
这是a:
[1, 2, [1, 2, 9]]
这是b:
[1, 2, [1, 2, 9], 9]
可以发现,不可变对象是独立的,因为复制的是值;而可变对象是指向同一个,因为复制的是引用。
如果想要完全独立的复制,可以使用深拷贝
import copy
b=[1,2,[1,2]]
a=copy.deepcopy(b)