




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
15-Python面的学习中,我们其实已经接触到了很多Pyhon对象比较和的例子,比如下面这个,判断a和b是否相等的i语句:ififa==l1l1=[1,2,l2=l2是l1的浅拷贝(shallowcopy)还是深度拷贝(deepcopy)a==b'=='VS等于(==)和is是Pyhon中对象比较常用的两种方式。简单来说,'=='操作符比较对象之间的值是否相等,比如下面的例子,表示比较变量a和b所指向的值是否相等。aa== 在Pyn中,每个对象的标识,都能通过函数idobject获得。因此,操作符,相当于比较对象之间的D是否相等,我们来看下面的例子:aa=b=a==ififaisifaisnot这里注意,比较操作符s'的速度效率,通常要优于'=='。因为i'操作符不能被重载,这样,Pyhon就不需要去寻找,程序中是否有其他地方重载了比较操作符,并去调用。执行比较操作符s',就仅仅是比较两个变量的D而已。但是'=='操作符却不同,执行a==b相当于是去执行a. 重载eq这个函数,其内部的处理通常会复杂 eq函数会去遍历列表中的 个例子t1t1=(1,2,[3,t2=(1,2,[3,t1==t2t1[t1==我们知道元组是不可变的,但元组可以嵌套,它里面的元素可以是列表类型,列表是可变的,所以如果我们修改了元组中的某个可变元素,那么元组本身也就改变了,之前用i'或者'=='操作符取得的结果,可能就不适用了。 起来看看Python中的浅拷贝(shallowcopy)和深度拷贝(deepcopy) l1l1=[1,2,l2=[1,2,l1==l1l1isl2s1=set([1,2,s2={1,2,s1==s2s1iss2这里,l2就是l12是1的浅拷贝。当然,对于可变的序列,我们还可以通过切片操作符':'完成浅拷贝,比如下面这个列表的例子:l1l1=[1,2,l2=l1==l1isl2importimportcopyl1=[1,2,3]l2= t1t1=(1,2,t2=t1==t1ist2这里,元组(1,2,3)只被创 到这里,对于浅拷贝你应该很清楚了。浅拷贝,是指重新分配块内存,创建个新的对象,里面的元素是原对象中子对象的。因此,如果原对象中的元素不可变,那倒无所谓;但如果元素可变,浅拷贝通常会带来些副作用,尤其需要注意。我们来看下面的例子:l1l1=[[1,2],(30,l2=list(l1)[[1,2,3],(30,40),[[1,2,3],(30,l1[1]+=(50,[[1,2,3],(30,40,50,60),[[1,2,3],(30,这个例子中,我们首先初始化了个列表l1,里面的元素是个列表和个元组;然后对l1执行浅拷贝,赋予l2。因为浅拷贝里的元素是对原对象元素的,因此l2中的元素和l1指向同个列表和元组对象。接着往下看。1pd0),表示对l1的列表新增元素100。这个操作不会对l2产生任何影响,因为l2和l1作为整体是两个不同的对象,并不共享内存地址。操作过后l2不变,l1会发生改变:[[1,[[1,2,3],(30,40),个元素和l1中的第个元素,共同指向同个列表,因此l2中的第个列表也会相对应的新增元素3。操作l1:l1:[[1,2,3],(30,40),l2:[[1,2,3],(30,最后是l1[1]+=(50,60),因为元组是不可变的,这里表示对l1中的第二个元组拼接,然后重新创建了l1:l1:[[1,2,3],(30,40,50,60),通过这个例子,你可以很清楚地看到使用浅拷贝可能带来的副作用。因此,如果我们想避免这种副作用,完 importimportl1=[[1,2],(30,l2=copy.deepcopy(l1)[[1,2,3],(30,40),[[1,2],(30, x=[1][1,y=copy.deepcopy(x)[1,上面这个例子,列表x中有指向自身的,因此x是个无限嵌套的列表。但是我们发现深度拷贝x到y后,程序并没有出现stackoverflow的现象。这是为什么呢?其实,这是因为深度拷贝函数deepcopy中会个字典,记录已经拷贝的对象与其ID。拷贝过程中,如defdefdeepcopy(x,memo=None,"""DeepcopyoperationonarbitraryPythonSeethestringformoreifmemoisNone:memo={}d=id(x)#查询被拷⻉对象x的y=memo.get(d,nil)#查询字典⾥是否已 了该对ifyisnotreturny#如果字典⾥已 了将要拷⻉的对象,则直接返 比较操作符'表示比较对象间的值是否相等,而i表示比较对象的标识是否相等,即它们是否指向同 个内存地址。 浅拷贝中的元素,是原对象中子对象的,因此,如果原对象中的元素是可变的,改变其也会影响拷贝 贝中会个字典,记录已经拷贝的对象及其ID,来提高效率并防止无限递归的发生。 x=[1]ycopy.deepcopy(x)#以下命令的输出是?x== SCAR2019-06-12应该会出错,因为x是个无限嵌套的列表,y深拷贝于x,按道理来讲x==y应该是True的,但进行比较 ,递归的层数是要限定的,不会无休下去,所以到了限定的层数,pyhon解释器会跳出错误。执行了下代码,也的确是跳出了ecusiono:umeusionphecdinoaion。之前课中做阶乘的例子,如果大于 定的整数,也是会出现递归错误,究其原因也是pyho的递归层数是有限定的。defRecursionError:umrecursiondepthexceededinimportsyshlz-1232019-06-12x==y出现如下错误信息,推测原因是x与y的列表进行项项比较,因无限嵌套,导致递归深度失败。RecursionError:umrecursiondepthexceededin[4赞yshan2019-06-12深拷贝,都不可变[3赞]Hoo-Ah2019-06-12,里面有这句话Note:lloctedwontoverflowbecausethelargestosbeveisPY_SSIZE_T_MAX*98)6whalasfitsnasize_t.译过来就是新的重载方法不会溢出。使用深拷贝也不会溢1h2019-06-121)a=b= 致。juterNotebook返回的不样的[1赞] 个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此'x==y'会无限递归对比,出现stackoverflow。x==Traceback(mostrecentcallFile"<i>",line1,nReursionError:umrrdepthexceededinopyhhou2019-06-12开始猜想是printTrue,因为当xappend自身的时候,程序是没有报错的,返回的结果是:[1,[...]],deepcopyylistTrue。当然尝试的结果是报错sumrrdepthexceededinoon”,应该是内部的比较函数递归比较的时候递归深度过长,也就是列表的递归嵌套超过了其限度[1赞]比较操作符'is'的速度效率,通常要优于'=='。因为'is'操作符不能被重载,这样,Python就不需要去寻找,程序中是否有其他地方重载了比较操作符,并去调用。执行比较操作符'is',就仅仅是比较两个变量的ID而已。list的切片和list另外 >>>import>>>x=>>>>>>x>>>>>>File"<stdin>",line1,inRecursionError:umrecursiondepthexceededinLone2019-06-13浅拷贝的例子让起了《流畅的PythonWing·三金2019-06-13符号调用的是eqis的结果取决于id,即是否指向 对is操作符无法重载,速度快;==操作符每次使用Python内部需要寻找是否有其他地方重载了比较操作符,而且重载般会伴随着更复杂的比较处理操作出于对性能优化的考虑,-5~256的整型数字在首次创建时会开辟数组型的缓存,以便重复返回相同的引a=b=aisb#a=b=a==b#Trueaisb#比较变量与单例(Singleton)is,ifais通常对于不可变的变量,==/is的结果是固定的,但是如果子变量是可变的(如(1,2,[3,4])),那么有t1=(1,[2,t2=(1,[2,t1==t2#t1==t2# 浅拷贝方式:list/set/dict/tuple;:(切片);l1=[1,l2=l1isl2#s1={1,s2=s1iss2#l1=[1,l2=l1isl2#importcopyl1=[1,2]l2=子对象可变时,最好用#l1=[[1,2],(30,l2=l1.append(100l2l1[0].append(3l2l1[150l2#deepl1=[[1,2],(30,l2=copy.deepcopy(l1)#任意操作,能互相算我tupletuplet1=(1,t2=t1==t2#Truet1ist2#x=[1]x.append(x)#x=[1,y=copy.deepcopy(x)#y=[1,上面这stackoverflow#原因是deepcopy会个字典用于记录已经拷贝的【对象+id】,若字典中已经了将要拷贝的xisy#x==y#RecursionError:umrecursiondepthexceededinz=zisx#code22019-06-13程序员人生2019-06-13defc=d=print(cisd)python3.7.22019-06-1312:05:15NG2019-06-12运行代码错。原因是进行"=="时需要递归对比每个元素,该循环是个无限循环(无限个元素)。然而python专门设置的种机制用来防止无限递归造成Python溢出,换句话说不能遍历比较到所有值,所以报错“RecursionError:umrecursiondepthexceededincomparison”路伴友行2019-06-12x和y各自形成 个闭Jason2019-06-12徐2019-06-12a=b=在python解释器中使用id查看确实内存地址不同,但是使用vscode同样也是python解释器,内存地址是思考题中xYSS2019-06-12ifyisnot老师,请问这是什么意思呢,_nil是个list,为什么不用ynotinJ
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 广东华南师大附中2025届高一下化学期末监测模拟试题含解析
- 合肥社区人员管理办法
- 机械维修制度管理办法
- 趣味性与原动力在学习和生活中的作用研究
- 北京预售许可管理办法
- 办公室综合管理和服务标准指南
- 板材加工安全管理办法
- 数字金融韧性增强对跨境电商影响的深度探究与对策建议
- 校务职工书屋管理办法
- 公益广告阵地管理办法
- 存量房的买卖合同
- 以工代赈群众务工组织方案
- 义务教育新课标必背古诗词135篇
- 营养专科护士总结汇报
- 热射病科普宣传
- 6S视觉管理之定置划线颜色管理及标准样式
- 数字资产的监管框架
- DL∕T 5783-2019 水电水利地下工程地质超前预报技术规程
- 100MW400MWh全钒液流电池储能电站项目可行性研究报告写作模板-拿地申报
- 老版入团志愿书表格完整
- 四柱万能液压机液压系统 (1)讲解
评论
0/150
提交评论