列表赋值、切片、工厂函数,深浅赋值

赋值

1 >>> a=[1,2,[3,4]]
2 >>> b=a
3 >>> c=a
4 >>> a is b
5 True
6 >>> c is a
7 True

赋值完还是同一个对象,地址内容完全一样

切片

1 >>> a=[1,2,[3,4]]
2 >>> b=a[:]
3 >>> b is a
4 False
5 >>> id(a),id(b)
6 (2192816216904, 2192816215240)
7 >>> id(a[2]),id(b[2])
8 (2192816228424, 2192816228424)
9 >>> 

切片是不同的两个对象,只是对内容的引用,因此内容的地址是一样的
工厂函数

1 >>> a=[1,2,[3,4]]
2 >>> c=list(a)
3 >>> a is c
4 False
5 >>> id(a),id(c)
6 (2192816252616, 2192816268424)
7 >>> id(a[2]),id(c[2])
8 (2192816259784, 2192816259784)

浅复制

1 >>> import copy
2 >>> a=[1,2,[3,4]]
3 >>> b=a.copy()
4 >>> b is a
5 False
6 >>> id(a),id(b)
7 (2192816286728, 2192816270152)
8 >>> id(a[2]),id(b[2])
9 (2192816284168, 2192816284168)

因此,切片,工厂函数,浅复制的作用相同
深复制

1 >>> a=[1,2,[3,4]]
2 >>> b=copy.deepcopy(a)
3 >>> [id(x) for x in [a,b]]
4 [2192815840328, 2192816284424]
5 >>> [id(x) for x in a]
6 [1593201440, 1593201472, 2192805444360]
7 >>> [id(x) for x in b]
8 [1593201440, 1593201472, 2192805417288]

可见,深复制已经不是对内容的引用了。深复制前后两个对象是完全不同的,不再是简单的引用了,需要注意前两个元素地址相同,第三个地址不同

下面对比下赋值,与切片(工厂函数,浅复制)

赋值:完全相同的两个对象,单个改变里面的对象,两个全变。但是当整体改变a时,相当于a已经换了引用的对象,b保持不变

1 >>> a=[1,2,[3,4]]
2 >>> b=a
3 >>> a[0],a[1],a[2]=3,4,5
4 >>> b
5 [3, 4, 5]
6 >>> a=[4,5,6]
7 >>> b
8 [3, 4, 5]

切片:使用切片两个对象是不相同的,首先分析改变列表里面不可变元素,序列化元素放到深浅复制里面分析

       a,b 两个对象是不同的,但是里面的内容,以及内容的地址时相同的。

   这个情况与赋值不同。

  为什么会出现这种情况呢?

图片参考:http://python.jobbole.com/82294/

浅复制创建了一个新的对象b,但是由于懒惰,只使用了原始元素的内存地址。

a中的第一个元素是不可变对象,所以重新赋值的使用了新的地址,但是b这个不同的对象,依然指向原始地址。

对于a中第三个元素,是一个列表,我们改变的是里面的元素。由上面改变a[1]可以看到,a的地址并没有改变,而我们引用的是

第三个元素的地址,所以改变a[2]或b[2],a,b会一起变

  
深复制

由上面的深复制可以看出,当列表中存在列表,使用深复制时,地址是不相同的。所以你改变a,b肯定不变啊。

最重要的问题:深复制,切片,工厂函数等 a,b,的前两个元素地址时一样的。为什么呢:非容器类型(比如数字,字符串和其他"原子"类型的)没有被拷贝一说,只是对其

        进行引用,只要修改,就会产生新的对象。(难以理解)

 

posted @ 2018-07-21 01:40  婆山岭下  阅读(72)  评论(0)    收藏  举报