list[] 和 list[:] 的理解
首先,python中没有赋值的说法,只有名称到对象的引用;
list2 = list1是把list1所指的对象绑定到名字list2上,没有产生新list,只是新增了一个引用;
正因为两个名称指向的同一个对象,所以修改list1,那么list2也会改变;
通俗理解:以前有一套三室一厅的房子,户主叫list1。后来list1和list2结婚,房产证上户主的名字加了一个,但房子还是只有一套。list1如果把客厅刷成了蓝色,那list2回家的时候会发现客厅是蓝色的了。
而list2 = list1[:]则是把list1通过切片运算取得的新list对象绑定到list2上,产生了新list,名称和引用也不同,所以,修改其中一个,另一个不会变。
注意,这里的切片是浅拷贝,参考下面的笔记。
浅拷贝会创建新对象,其内容是原对象的引用。
浅拷贝有三种形式:切片操作,工厂函数,copy模块中的copy函数。
比如对:a = [1,2,3,"hello",["python","C++"]]
1、切片操作:b = a[:] 或者 b = [each for each in a]
2、工厂函数:b = list(a)
3、copy函数:b = copy.copy(a)
浅拷贝产生的b不再是a了,使用is可以发现他们不是同一个对象,使用id查看,发现它们也不指向同一片内存。但是当我们使用 id(x) for x in a 和 id(x) for x in b 时,可以看到二者包含的元素的地址是相同的。
在这种情况下,a和b是不同的对象,修改b理论上不会影响a。
比如b.append([4,5]):
b = a[:]
b.append("ADD")
输出:a [1, 2, 3, 'hello', ['python', 'C++']] b [1, 2, 3, 'hello', ['python', 'C++'], 'ADD']
注:浅拷贝之所以称为浅拷贝,是它仅仅只拷贝了一层,在a中有一个嵌套的list,如果我们修改了它,情况就不一样了。
深拷贝(deep copy)
深拷贝只有一种形式,copy模块中的deepcopy函数。
和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。因而,它的时间和空间开销要高。