朋友们,如需转载请标明出处:https://blog.csdn.net/jiangjunshow
声明:在人工智能技术教学期间,不少学生向我提一些python相关的问题,所以为了让同学们掌握更多扩展知识更好地理解AI技术,我让助理负责分享这套python系列教程,希望能帮到大家!由于这套python教程不是由我所写,所以不如我的AI技术教学风趣幽默,学起来比较枯燥;但它的知识点还是讲到位的了,也值得阅读!PS:看不懂本篇文章的同学请先看前面的文章,循序渐进每天学一点就不会觉得难了!
有一些对象和操作确实会在原处改变对象。例如,在一个列表中对一个元素进行赋值确实会改变这个列表对象,而不是生成一个新的列表对象。对于支持这种在原处修改的对象,共享引用时的确需要加倍的小心,因为对一个变量名的修改会影响其他的变量。
为了进行深入地理解,让我们再复习一下之前已经介绍过了的列表对象。回忆一下列表,它在方括号中进行编写,是其他对象的简单集合:
>>> L1 = [2,3,4]
>>> L2 = L1
L1是一个包含了对象2、3和4的列表。在列表中的元素是通过它们的位置进行读取的,所以L1[0]引用对象2,它是列表L1中的第一个元素。当然,列表自身也是对象,就像整数和字符串一样。在运行了第二条语句后,L1和L2引用了相同的对象。如果我们执行下面的语句:
>>> L1 = 24
L1直接被设置成了一个不同的对象,L2仍是引用最初的列表。但如果我们像下面这样赋值,那么就会有明显不同的效果。
>>> L1[0] = 24 # An in-place change
>>> L1 # L1 is different
[24,3,4]
>>> L2 # But so is L2!
[24,3,4]
在这里,没有改变L1,改变了L1的一个元素。这类修改会覆盖列表对象中的某部分。因为这个列表对象是L1和L2共享的,所以改变也会对L2产生影响,因为它与L1都引用了相同的对象。另外,我们实际上并没有改变L2,但是它的值发生了变化。
如果你不想要上面的现象发生,那么你需要拷贝对象,而不是创建引用。有很多种拷贝一个列表的办法,包括内置列表函数以及标准库的copy模块,也许最常用的办法就是从头到尾的分片。
>>> L1 = [2,3,4]
>>> L2 = L1[:] # Make a copy of L1
>>> L1[0] = 24
>>> L1
[24, 3,4]
>>> L2 # L2 is not changed
[2,3,4]
这里,对L1的修改不会影响L2,因为L2引用的是L1所引用对象的一个拷贝。也就是说,两个变量指向了不同的内存区域。
注意这种分片技术无法应用在某些类型上,例如字典和集合,因为它们不是序列。复制一个字典或集合应该使用X.copy()方法调用。而且,注意标准库中的copy模块有一个通用的复制任意对象类型的调用,也有一个拷贝嵌套对象结构的调用(例如,嵌套了列表的一个字典):
import copy
X = copy.copy(Y) # Make top-level "shallow" copy of any object Y
X = copy.deepcopy(Y) # Make deep copy of any object Y: copy all nested parts