1.is和==的区别
Python中的对象包含三要素:id、type、value。
1.id
在内存中存储的位置,用来唯一标识一个对象
-id(变量名)查看id
2.type
标识对象的类型
type(变量名)查看数据类型
3.value
is判断的是a对象是否就是b对象,是通过type,value,id三者同时来判断的。
==判断的是a对象的值是否和b对象的值相等,是通过value,type来判断的。
换句话说:
1)若a is b=====>True,则a==b一定相等,返回True;
2)若a==b ====> True, a is b 不一定;
a=3 b=a print(id(a),id(b)) print(type(a),type(b)) print(a,b) print(a is b) print(a==b)
a=[3,4,5] b=a.copy() print(id(a),id(b)) print(type(a),type(b)) print(a,b) print(a is b) print(a==b)
2.深拷贝和浅拷贝
1.定义:
在Python中对象的赋值其实就是对象的引用。当创建一个对象,把它赋值给另一个变量的时候,python并没有拷贝这个对象,只是拷贝了这个对象的引用而已。
浅拷贝:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。也就是,把对象复制一遍,但是该对象中引用的其他对象不复制
深拷贝:外围和内部元素都进行了拷贝对象本身,而不是引用。也就是,把对象复制一遍,并且该对象中引用的其他对象我也复制。
2.应用的范围:
1,切片可以应用于:列表、元组、字符串,但不能应用于字典。
2,深浅拷贝,既可应用序列(列表、元组、字符串),也可应用字典。
1,减少内存的使用
2,以后在做数据的清洗、修改或者入库的时候,对原数据进行复制一份,以防数据修改之后,找不到原数据。
####对于不可变对象的深浅拷贝:
不可变对象类型,没有被拷贝的说法,即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。一句话就是,不可变类型,不管是深拷贝还是浅拷贝,地址值和拷贝后的值都是一样的。
1.浅拷贝:
1)直接赋值(li1 = li): 只传递对象的引用, li1指向对象li的内存地址空间, 因此, 原有列表li改变, 被赋值的li1也会做相应的改变
2)li2=li.copy()):li和li2的内存地址不同,因此原始数据改变 , 子对象不改变.
li2=li[:]
2.深拷贝:
import copy
li3=copy.deepcopy(li))
li和li3的内存地址不同,包含子对象的拷贝, 所以原始对象改变并不会造成深拷贝里面任何子项的改变.
####对于可变对象的深浅拷贝:
=浅拷贝:值相等,地址相等
copy浅拷贝:值相等,地址不相等
deepcopy深拷贝:值相等,变量地址不同,但子对象地址相等
import copy a=[1,2,3,4] #a.append(5) b1=a b2=a[:] b3=a.copy() b4=copy.deepcopy(a) print(a,b2,b3,b1,b4) print(id(b1),id(b2),id(b3),id(a),id(b4)) print(id(b2[0]),id(b3[0]))
***面试常问:请简述赋值, 深拷贝和浅拷贝的区别?(python中如何拷贝一个对象?)
- 直接赋值(li1 = li): 只传递对象的引用, li1指向对象li的内存地址空间,
因此, 原有列表li改变, 被赋值的li1也会做相应的改变.
- 浅拷贝(三种实现方式 eg: li2=li.copy()):li和li2的内存地址不同,
但是子对象的内存地址相同, 因此,原始数据改变 , 子对象也改变.
- 深拷贝(import copy, eg: li3=copy.deepcopy(li)), li和li3的内存地址不同,
包含子对象的拷贝, 所以原始对象改变并不会造成深拷贝里面任何子项的改变.
*** 当深拷贝和浅拷贝, 针对的对象全部是不可变数据类型时, 两者效果相同;
*** 当深拷贝和浅拷贝, 针对的对象包含是可变数据类型时, 两者才有上述区别;