看如下代码:
>>> spam = 42
>>> cheese = spam
>>> spam = 100
>>> spam
100
>>> cheese
42
将42赋值给spam变量, 然后拷贝spam中的值给cheese,然后将spam中的额值改为100,这不会影响cheese中的值,这是因为spam和
cheese是不同的变量,保存了不同的值。
但列表不是这样的, 当你将列表赋值给一个变量时, 实际上是将列表的“引用”赋值给了该变量。引用是一个值, 指向某些数据。
列表引用是指向一个列表的值。
>>> spam = [0, 1, 2, 3, 4, 5]
>>> cheese = spam
>>> cheese[1] = 'hello'
>>> spam
[0, 'hello', 2, 3, 4, 5]
当创建列表列表时, 你将对它的引用赋值给了变量, 但下一行只是将spam中的列表引用拷贝到cheese,而不是列表本身。这就是意味着
存储在spam和cheese中的值现在指向了同一个列表。底下只有一个列表, 因为列表本身从未被复制,所以当你修改cheese变量的第二个
元素时, 也修改了spam指向的同一个列表。
image.png
变量包含对列表值的引用,而不是列表值本身。但对于字符串和整数值,变量
就包含了字符串或整数值。在变量必须保存可变数据类型的值时,例如列表或字典,
Python 就使用引用。对于不可变的数据类型的值,例如字符串、整型或元组,Python
变量就保存值本身。
copy 模块的copy()和deepcopy()函数
如果我们希望对列表或字典的修改不会影响到原来的列表或者字典的话, Python提供了copy模块, 其中包含copy()和deepcopy()函数。第一个函数copy.copy()可以用来复制列表或字典这样的可变值, 而不只是复制引用。
>>> import copy
>>> spam = ['A', 'B', 'C', 'D']
>>> cheese = copy.copy(spam)
>>> cheese[1] = 'hello'
>>> cheese
['A', 'hello', 'C', 'D']
>>> spam
['A', 'B', 'C', 'D']
现在spam和cheese变量指向独立的列表
image.png
如果复制的列表中包含了列表,就是用deepcopy()函数来代替,deepcopy()函数将同时复制它们内部的列表。
>>> spam = ['a', 'c', [1,2,3],'d']
>>> cheese = copy.copy(spam)
>>> cheese
['a', 'c', [1, 2, 3], 'd']
>>> cheese[1] = 'hello'
>>> cheese
['a', 'hello', [1, 2, 3], 'd']
>>> spam
['a', 'c', [1, 2, 3], 'd']
>>> cheese = copy.deepcopy(spam)
>>> cheese
['a', 'c', [1, 2, 3], 'd']
>>> cheese[2]
[1, 2, 3]
>>> cheese[1] = 'world'
>>> cheese
['a', 'world', [1, 2, 3], 'd']
貌似copy()也可以复制内部包含列表的列表。