Python 为什么索引超出范围的子字符串切片工作?

Python 为什么索引超出范围的子字符串切片工作?,python,string,substring,Python,String,Substring,为什么'example'[999:9999]不会导致错误?既然'example'[9]是这样做的,那么背后的动机是什么 从这个行为中,我可以假设'example'[3]本质上/在内部与'example'[3:4]不同,即使两者产生相同的'm'字符串。切片不是由内置类型检查的边界。虽然你的两个例子似乎有相同的结果,但它们的工作方式不同;用列表来代替它们。你说得对'example'[3:4]和'example'[3]是根本不同的,在序列的边界之外切片(至少对于内置的)不会导致错误 一开始可能会让人惊

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


从这个行为中,我可以假设
'example'[3]
本质上/在内部与
'example'[3:4]
不同,即使两者产生相同的
'm'
字符串。

切片不是由内置类型检查的边界。虽然你的两个例子似乎有相同的结果,但它们的工作方式不同;用列表来代替它们。

你说得对<代码>'example'[3:4]和
'example'[3]
是根本不同的,在序列的边界之外切片(至少对于内置的)不会导致错误

一开始可能会让人惊讶,但仔细想想,这是有道理的。索引返回单个项目,但切片返回项目的子序列。因此,当您尝试索引一个不存在的值时,没有什么可以返回的。但是,当您在边界之外切片一个序列时,仍然可以返回一个空序列

这里令人困惑的部分原因是字符串的行为与列表稍有不同。看看对列表执行相同操作时会发生什么:

>>> [0, 1, 2, 3, 4, 5][3]
3
>>> [0, 1, 2, 3, 4, 5][3:4]
[3]
这里的区别是显而易见的。在字符串的情况下,结果似乎是相同的,因为在Python中,字符串之外没有单独的字符。单个字符只是一个1字符的字符串


(有关在序列范围外切片的确切语义,请参见。)

为了添加指向序列中健壮部分的答案:

给定一个类似于
s[i:j:k]
的切片表达式


带有步骤k的从i到j的s的切片被定义为具有索引
x=i+n*k
的项目序列,因此
0
[999:9999]
不是索引,而是切片,并且具有不同的语义。从python简介中可以看出:“退化切片索引处理得很优雅:太大的索引将被字符串大小替换,小于下限的上界将返回一个空字符串。”@Wooble这是实际值answer@Wooble你知道为什么会这样吗?谢谢你的澄清。为什么?您必须询问Guido,但我认为能够假设一个片段总是与原始序列相同类型的序列是很优雅的。@Lapinot是的,我已经编写了依赖于此行为的代码。不幸的是,我记不起确切的代码,所以我不能告诉你原因。可能与子字符串有关;获取空字符串有时可能正是您想要的。超出范围的索引可能会返回
None
,而不是出错-这是Python在无返回内容时的常见惯例。@MarkRansom,这是真的;但是在这种情况下,返回
None
会使在列表中区分越界索引和
None
值变得更加困难。但即使有解决方法,我仍然很清楚,当给定一个越界片段时,返回一个空序列是正确的。这类似于执行两个不相交集的并集。只是要清楚,我没有说你错了。我明白你关于列表中的
None
值的观点。@markransem,我知道——如果我听起来是防御的话,我很抱歉。实际上,我只是想找个借口来引用集合论:).Aw,除了我说的是“并集”而不是“交集”。大概当
k
为正时,
I
j
在较小时也会增加到
-len(s)
?e、 g.
s='bac';s[-100:2]==s[-len(s):2]
@Chris_Rands当
k
为正数时,Python将缩放
i
j
,以便它们符合序列的边界。在您的示例中,
s[-100:2]==s[0:2]
==s[-len(s):2]
,顺便说一下)。类似地,
s[-100:100]==s[0:2]
。很好,谢谢。这是对@speedplane上述评论的更好回应。