欢迎关注小睿的微信公众号:郭小睿同学
,每天更新小知识、笔记、案例、学习资源~
今悟引用,遂做笔记,以供大观~
spam = 45
cheese = spam
spam = 100
print(spam)
print(cheese)
在运行时,该程序输出如下:
100
45
你将42赋值给spam变量,然后拷贝spam的值,将它赋值给变量cheese,当稍后将spam中的值改变成100时,还不会影响cheese中的值。这是因为这两个变量是不同的变量,保存了不同的值。
当你将列表赋值给一个变量的时候,实际上是将列表的引用赋值给了该变量。引用是一个值,指向某些数据。列表引用是指向一个列表的值。
spam = [0, 1, 2, 3, 4, 5]
cheese = spam
cheese[1] = "hello"
print(spam)
print(cheese)
在运行时,该程序输出如下:
[0, 'hello', 2, 3, 4, 5]
[0, 'hello', 2, 3, 4, 5]
看到这里,大家也许觉得很奇怪,代码只改变了cheese列表,但是似乎cheese和spam列表同时发生了改变。
当创建列表时,spam = [0, 1, 2, 3, 4, 5]
你将对它的引用赋值了变量,但是cheese = spam
只是将spam中的列表引用
拷贝到cheese,而不是列表值的本身
。
这就意味存储在spam和cheese中的值,现在指向
了同一个列表。所以,这里不叫拷贝,而是引用
。
变量包含对列表值的引用,而不是列表值本身。但是对于字符串和整数值,变量就包含了字符串或整数值。
在变量必须保存可变数据类型的值时,例如列表或字典,Python就会使用引用。对于不可变的数据类型的值,例如字符串、整型或元组,Python变量就保存值本身。
虽然Python变量在技术上包含了对列表或者字典值的引用
,但是人们通常随意地说,该变量包含了列表或字典~233
当函数被调用时,参数的值被复制给变元。对于列表和字典,就意味变元得到的引用的拷贝
。
def eggs(someParameter):
someParameter.append("Hello")
spam = [1, 2, 3]
eggs(spam)
print(spam)
当eggs()
被调用时,没有使用返回值来为spam赋值。相反,它直接当初修改了该列表。
在运行时,该程序输出如下:
[1, 2, 3, 'Hello']
尽管spam和someParameter包含了不同的引用,但是他们都指向了相同的列表
。这也就是为什么函数内的append()方法被调用在函数调用返回后,仍然会对该列表产生影响。
倘若你忘了Python处理可变数据时采用这种方式,可能会导致令人困惑的缺陷。
在处理列表和字典时,尽管传递引用常常时最方便的方法,但是如果函数修改了传入的列表或字典,你可能并不希望这些变动影响原来的列表或字典。
要做到这一点,Python提供了名为copy
的模板。
函数copy.copy()
,可以复制列表或字典这样的可变值
,而不是复制引用。
import copy
spam = [1, 2, 3, 4, 5]
cheese = copy.copy(spam)
cheese[1] = "A"
print(spam)
print(cheese)
在运行时,该程序输出如下:
[1, 2, 3, 4, 5]
[1, 'A', 3, 4, 5]
现在spam和cheese变量指向独立的列表
,这就是为什么你修改了列表,只有cheese中列表被改变。
如果要复制列表引用,那就使用copy.deepcopy()
函数来代替。