在Python中选择子序列的困惑
可能重复的问题:
Python 切片表示法
我对 Python 中的子序列选择有点困惑。假设我有以下代码:
>>> t = 'hi'
>>> t[:3]
'hi'
>>> t[3:]
''
>>> print t[:3] + t[3:]
hi
>>> print t[3]
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
print t[3]
IndexError: string index out of range
请解释一下这段代码在 Python 中是怎么工作的。
3 个回答
t[start:stop]
这个写法会打印出所有在起始位置和结束位置之间的元素,也就是说,它会显示所有满足条件的元素 x,条件是 start 小于等于 x 且 x 小于 stop。如果某些元素不存在,它就不会显示这些元素。
而 t[index]
这个写法就不一样了,如果指定的位置没有元素,它会报错。
在你的例子中,只有 t[0]='h'
和 t[1]='i'
这两个元素存在,这就解释了你得到的结果。
print t[3:]
应该什么都不返回,而不是返回 'hi',在我的 Python 解释器中也是这样。
我总觉得序列的行为有点搞笑,因为它们允许切片超出范围。不过,这个行为是有说明的,具体在文档的第4点,讲的是序列类型的切片:
从 i 到 j 的切片定义为索引 k 的项目序列,满足 i <= k < j。如果 i 或 j 大于 s 的长度,就用 s 的长度。如果 i 被省略或是 None,就用 0。如果 j 被省略或是 None,就用 s 的长度。如果 i 大于或等于 j,切片就是空的。
还有第5点,讲的是带有可选步长参数的切片:
从 i 到 j 的切片,步长为 k,定义为索引 x = i + n*k 的项目序列,满足 0 <= n < (j-i)/k。换句话说,索引是 i, i+k, i+2*k, i+3*k,依此类推,直到达到 j(但不包括 j)。如果 i 或 j 大于 s 的长度,就用 s 的长度。如果 i 或 j 被省略或是 None,它们就变成“结束”值(结束的地方取决于 k 的符号)。注意,k 不能为零。如果 k 是 None,就当作 1 来处理。
需要注意的是,如果你查看第3点(讲的是 s[index]
),就会发现没有对应的处理超出范围的索引转换为有效索引的说明。
子序列或者切片的表示方式比较宽容。比如,t[:3]
这个写法会从 t
的开头切出一部分,直到第三个元素为止,或者到最后一个元素,哪个先到就取哪个。而 t[3:]
则是从第三个元素开始切,直到最后一个元素,前提是第三个元素存在。直接索引,比如 t[3]
,就比较严格了;你必须确保这个元素存在,否则就会出错。使用切片的时候,如果结束的索引超出了范围,你会得到整个原始列表;如果开始的索引超出了范围,你会得到一个空列表。