为什么子串切片索引超出范围在Python中有效?

ijv*_*rig 72 python string substring

为什么不'example'[999:9999]导致错误?既然'example'[9]做,什么是其背后的动机是什么?

从这种行为我可以假设'example'[3],基本上/内部,不一样'example'[3:4],即使两者都产生相同的'm'字符串.

sen*_*rle 57

你说的没错!'example'[3:4]并且'example'[3]根本不同,并且在序列的边界之外切片(至少对于内置插件)不会导致错误.

一开始可能会令人惊讶,但是当你想到它时它才有意义.索引返回单个项目,但切片返回项目的子序列.因此,当您尝试索引不存在的值时,无法返回任何内容.但是当您在边界之外切割序列时,仍然可以返回空序列.

这里令人困惑的部分原因是字符串与列表的行为略有不同.看看当你对列表做同样的事情时会发生什么:

>>> [0, 1, 2, 3, 4, 5][3]
3
>>> [0, 1, 2, 3, 4, 5][3:4]
[3]
Run Code Online (Sandbox Code Playgroud)

这里的区别是显而易见的.在字符串的情况下,结果看起来是相同的,因为在Python中,字符串之外没有单个字符.单个字符只是一个1个字符的字符串.

(有关在序列范围之外切片的确切语义,请参阅mgilson的答案.)

  • @MarkRansom,这是真的; 但是在这种情况下返回"无"将使得在列表中的越界索引和"无"值之间更难分辨.但即使有一个解决方法,我仍然清楚,当给出一个越界切片时,返回一个空序列是正确的做法.它类似于执行两个不相交集的并集. (6认同)
  • 噢,除了我说"联盟"而不是"交集". (4认同)

mgi*_*son 25

为了添加指向文档中的健壮部分的答案:

给出切片表达式s[i:j:k],

具有步骤k的从i到j的s的片被定义为具有索引x = i + n*k的项的序列,使得0 <= n <(ji)/ k.换句话说,索引是i,i + k,i + 2*k,i + 3*k等等,当到达j时停止(但是从不包括j).当k为正时,如果它们更大,则i和j减少为len(s)

如果你写的x = i + n*k,Python是返回0 <= n < (j-i)/k,因为i,你的步骤是积极的(i+k-默认).


Ign*_*ams 7

切片不受内置类型的限制.虽然你的两个例子似乎都有相同的结果,但它们的工作方式不同; 尝试使用列表代替它们.