当我们根据单个索引进行取值时,如果索引越界,就会得到报错:“IndexError: list index out of range”。

>>> li = [1, 2]
>>> li[5]
Traceback (most recent call last):File "<stdin>", line 1, in <module>
IndexError: list index out of range

对于一个非空的序列对象,假设其长度为 length,则它有效的索引值是从 0 到(length - 1)。如果把负数索引也考虑进去,则单个索引值的有效区间是 -length, length - 1 闭区间。

但是,当 Python 切片中的索引超出这个范围时,程序并不会报错。

>>> li = [1, 2]
>>> li[1:5]  # 右索引超出
[2]
>>> li[5:6]  # 左右索引都超出
[]

其实,对于这种现象,官方文档中有所介绍:

The slice of s from i to j is defined as the sequence of items with index k such that i <= k < j. If i or j is greater than len(s), use len(s). If i is omitted or None, use 0. If j is omitted or None, use len(s). If i is greater than or equal to j, the slice is empty.

也就是说:

  • 当左或右索引值大于序列的长度值时,就用长度值作为该索引值;
  • 当左索引值缺省或者为 None 时,就用 0 作为左索引值;
  • 当右索引值缺省或者为 None 时,就用序列长度值作为右索引值;
  • 当左索引值大于等于右索引值时,切片结果为空对象。

对照上面的例子,可以得到:

>>> li = [1, 2]
>>> li[1:5]  # 等价于 li[1:2]
[2]
>>> li[5:6]  # 等价于 li[2:2]
[]

归结起来一句话:Python 解释器把可能导致索引越界的操作给屏蔽了,你的写法可以很自由,但是最终的结果会被死死限制在合法的索引区间内。

对于这个现象,我其实是有点疑惑的,为什么 Python 不直接报索引越界呢,为什么要修正切片的边界值,为什么一定要返回一个值呢,即便这个值可能是个空序列?

当我们使用“li5:6”时,至少在字面意义上想表达的是“取出索引从 5 到 6 所对应的值”,就像是在说“取出书架上从左往右数的第 6 和 7 本书”。

如果程序是如实地遵照我们的指令的话,它就应该报错,就应该说:对不起,书架上的书不够数。

实话说,我并没有查到这方面的解释,这篇文章也不是要给大家科普 Python 在设计上有什么独到的见解。恰恰相反,这篇文章的主要目的之一是希望得到大家的回复解答。

在 Go 语言中,遇到同样的场景时,它的做法是报错“runtime error: slice bounds out of range”。

在 Rust 语言中,遇到同样的场景时,它的做法是报错“byte index 5 is out of bounds of ......”。

在其它支持切片语法的语言中,也许还有跟 Python 一样的设计。但是,我还不知道有没有(学识浅薄)……

最后,继续回到标题中的问题“Python 的切片为什么不会索引越界”。我其实想问的问题有两个:

  • 当切片语法中的索引超出边界时,为什么 Python 还能返回结果,返回结果的计算原理是什么?
  • 为什么 Python 的切片语法要允许索引超出边界呢,为什么不设计成抛出索引错误?

对于第一个问题的回答,官方文档已经写得很明白了。

对于第二个问题,本文暂时没有答案。

Python 的切片语法为什么不会出现索引越界呢?相关推荐

  1. python—字符串切片

    python-字符串切片 语法:字符串[开始索引:结束索:步长] 练习: 截取从2-5位置的字符串 def demo():s = "0123456789"print(s[2:6]) ...

  2. python切片语法-python切片语法

    广告关闭 2017年12月,云+社区对外发布,从最开始的技术博客到现在拥有多个社区产品.未来,我们一起乘风破浪,创造无限可能. 我们怎么能用列表做这个(x )以及这个操作有什么作用?... pytho ...

  3. python切片语法-Python新手学习基础之数据类型——字符串的切片截取

    切片截取是python中字符串常见的一些操作,我们会在这篇文章里详细介绍,切片截取的作用是获取子字符或子字符串. 实际上,我们要做的就是使用索引,用冒号分隔两个索引,形式为:变量[头下标:尾下标],冒 ...

  4. python切片语法-彻底搞懂Python切片操作

    在利用Python解决各种实际问题的过程中,经常会遇到从某个对象中抽取部分值的情况,切片操作正是专门用于完成这一操作的有力武器.理论上而言,只要条件表达式得当,可以通过单次或多次切片操作实现任意切取目 ...

  5. python切片语法-Python切片符号(:)用法及示例

    Python的切片符号语法 s[start:end:step] s:被切片的对象 start:切片迭代的起始索引 end:切片迭代的终止索引,但end索引不包含在切片内 step:切片步长 其中,st ...

  6. python切片语法-Python字符串切片操作知识详解

    python 中关于字符串切片的一个问题 aa[0:6] 表示取 第0,1,2,3,4,5 位的数据 所以是6个 123456 aa[:-1] 表示取开始到倒数第二位的数据 所以也是123456 就像 ...

  7. python切片语法-详解Python 切片语法

    Python的切片是特别常用的功能,主要用于对列表的元素取值.使用切片也会让你的代码显得特别Pythonic. 切片的主要声明如下,假设现在有一个list,命名为alist: alist = [0,1 ...

  8. 深入讨论Python中的序列切片语法

    本小节深入探讨Python中的序列切片语法. 切片-slicing可以获取序列的子序列(列表,字符串-): numbers = [x for x in range(10)] print("n ...

  9. python 列表切片负值,详解Python 切片语法

    Python的切片是特别常用的功能,主要用于对列表的元素取值.使用切片也会让你的代码显得特别Pythonic. 切片的主要声明如下,假设现在有一个list,命名为alist: alist = [0,1 ...

  10. python列表切片后得到剩余列表_python列表切片和嵌套列表取值操作详解

    python列表切片和嵌套列表取值操作详解 给出列表切片的格式: [开头元素::步长] # 输出直到最后一个元素,(最后一个冒号和步长可以省略,下同) [开头元素:结尾元素(不含):步长] # 其中, ...

最新文章

  1. ref与out的区别
  2. android 编程klinon,android - 您尚未接受以下SDK组件的许可协议
  3. 谷歌正式开源Model Search!自动优化并识别AI模型,最佳模版唾手可得
  4. 用php实现一个简易的web表单生成器,PHP—Web表单生成器
  5. VTK:隐式函数之ImplicitSphere
  6. dart系列之:dart中的异步编程
  7. spring mvc学习(42):restful的编辑功能实现
  8. 学点数学(2)-特征函数
  9. Proteus安装图文教程
  10. 华硕笔记本触摸鼠标手势无效怎么办
  11. 近期刷题总结[2019 03 09]
  12. 只能吃土豆的牛牛(二进制枚举)
  13. BIGEMAP如何发布百度离线地图及二次开发API
  14. 对话腾讯天琴赵伟峰:当音乐与科技结合,会碰撞出怎样的火花?
  15. 实战——幂等性+海量数据处理
  16. 我们遭遇攻击——2004全球信息安全调研
  17. Hibernate中:cannot simultaneously fetch multiple bags的问题
  18. 一入职就遇上Mysql亿级优化,方案都改了5遍
  19. 【Power BI】通过Power BI DAX获取每月活动用户数量
  20. 不要再问Python了!

热门文章

  1. 揭秘勒索病毒背后黑客组织:偷了官方网络武器库
  2. 《解决nPlayer卡顿,玩转WebDAV》
  3. 斐讯盒子刷android tv,【TV】斐讯盒子T1_YYFROM语音助手实用版(191129)
  4. 激励机制中的经济学和博弈论模型(2)
  5. PLSQL使用text import导入数据
  6. VLAN技术详解三(VLAN三种访问模式)
  7. 十六、 方差分析--使用Python进行双因素方差分析
  8. 基于matlab的瑞利衰落信道建模和仿真
  9. _beginThread如何传递多个参数
  10. android 截屏 简书,Android基础 截屏ScreenCapture