当前位置: 首页 > 后端技术 > Python

为什么Python的切片索引不会越界?_0

时间:2023-03-25 22:18:46 Python

slice(切片)是Python中一个非常有特色的特性。在正式开始之前,我们先来回顾一下关于切片的知识。切片主要用在序列对象中,根据索引范围提取索引的内容。切片的写入格式:[i:i+n:m];其中,i为切片的起始索引值,当它在列表中的第一个时可以省略;i+n是切片的结束位置,当它在链表的最后时可以省略;m可以不提供,默认值为1,不允许为0,当m为负数时,列表将被反转。切片的基本含义是:从序列的第i个索引开始,一直到最后n位元素,按m个区间过滤。以下是一些有代表性的例子,基本涵盖了切片语法的使用要点:#@Python猫li=[1,4,5,6,7,9,11,14,16]#下面的写法可以表示整个列表,其中X>=len(li)li[0:X]==li[0:]==li[:X]==li[:]==li[::]==li[-X:X]==li[-X:]li[1:5]==[4,5,6,7]#从1开始,取5-1个元素li[1:5:2]==[4,6]#从1开始,取5-1位元素,按2个区间过滤li[-1:]==[16]#取倒数第一个元素li[-4:-2]==[9,11]#从倒数第四个取-2-(-4)=2个元素li[:-2]==li[-len(li):-2]==[1,4,5,6,7,9,11]#从头开始??,取-2-(-len(li))=7位元素#当步长为负数时,先翻转list,然后截取li[::-1]==[16,14,11,9,7,6,5,4,1]#翻转整个列表li[::-2]==[16,11,7,5,1]#翻转整个列表list,press2区间过滤li[:-5:-1]==[16,14,11,9]#翻转整个list,取-5-(-len(li))=4个元素li[:-5:-3]==[16,9]#翻转entirelist,取-5-(-len(li))=4个元素,然后按3个区间过滤#切片的步长不能为0li[::0]#报错(ValueError:slicestepcannotbe零)像C/C++、Java、JavaScript这样的语言也支持一些“切片”功能,比如截取数组或者字符串,但是它们没有语法上的通用支持。根据维基百科,Fortran是第一个支持切片语法的语言(1966年),Python是最具代表性的语言之一。各大编程语言对切片的支持此外,像Perl、Ruby、Go、Rust等语言,虽然也有切片,但不如Python灵活自由(因为支持步进、负索引、默认索引).切片语法在编程语言中的基本用法可以满足大部分需求。不过Python切片也有一些高级用法,比如:切片占位符用法(可以实现列表的赋值、删除和拼接)、自定义对象实现切片函数、迭代器切片(itertools.islice())、文件对象切片、etc.相关阅读:Python进阶:高级特性切片全面解读!切片的介绍和回顾就到这里。进入文章标题:为什么Python的切片语法不会导致索引越界?当我们基于单个索引取值时,如果索引越界,就会报错:“IndexError:listindexoutofrange”。>>>li=[1,2]>>>li[5]Traceback(最近调用最后):文件“”,第1行,在IndexError:列表索引超出范围的空序列对象,假设它的长度为length,它的有效索引值是从0到(length-1)。如果还考虑负索引,则单个索引值的有效范围是闭范围[-length,length-1]。但是当Python切片中的索引超出这个范围时,程序不会报错。>>>li=[1,2]>>>li[1:5]#右索引超过[2]>>>li[5:6]#左右索引都超过[]其实对于这种现象,官方在文档中是这样介绍的:s从i到j的切片定义为索引为k的item序列,满足i<=k>>li=[1,2]>>>li[1:5]#等价于li[1:2][2]>>>li[5:6]#相当于li[2:2][]一句话总结:Python解释器屏蔽了可能导致索引越界的操作。您可以自由编写,但最终结果将严格限制在合法索引范围内。范围内。对于这个现象,我其实有点疑惑。为什么Python不直接报索引越界,为什么要修正切片的边界值,为什么还要返回一个值,即使这个值可能是一个空序列?当我们使用“li[5:6]”时,至少在字面意义上,我们的意思是“取索引对应的从5到6的值”,这就像是在说“取从左边数起的书架数”右边的书6和7”。如果程序忠实地遵循我们的指令,它应该报告一个错误,它应该说:对不起,书架上的书不够。老实说,我没有找到这方面的解释,这篇文章也无意让你对科普Python的设计有什么独到的见解。相反,这篇文章的主要目的之一就是希望得到大家的解答。在Go语言中,遇到同样的场景,会报错“runtimeerror:sliceboundsoutofrange”。在Rust语言中,遇到同样的场景,会报错“byteindex5isoutofboundsof...”。在其他支持切片语法的语言中,可能也有和Python一样的设计。不过不知道有没有(小知识)……最后继续回到标题“Python的slice索引为什么不越界”中的问题。其实我想问两个问题:当slice语法中的索引超出边界时,为什么Python仍然返回结果,返回结果的计算原理是什么?为什么Python的切片语法允许越界索引,为什么它不被设计为抛出索引错误?第一个问题的答案,官方文档已经写的很清楚了。对于第二个问题,本文暂时没有答案。也许我很快就会找到答案,但这可能需要很长时间。不管怎样,这篇文章到这里就结束了。如果觉得文章还不错,欢迎关注公众号:Python编程学习圈,或者去编程学习网了解更多编程技术知识,还有海量干货学习资料!