>>> s = 'this_is_a_test' >>> s[1 : 5] 'his_'进一步,下面的语法及输出也很不难理解:
>>> s = 'this_is_a_test' >>> s[ : : 2] 'ti_sats'那么,下面的呢?
>>> s = 'this_is_a_test' >>> s[ : : -1] 'tset_a_si_siht' ## 为何s被反转了? >>> s[1 : 6 : -1] '' ## 为何只得到个空串? >>> s[6 : 1 : -1] 'si_si' ## 为何是这个结果?是不是觉得当slicing表达式的第3个参数(步长,"stride" or "step")为负数时,结果有点奇怪?
1. 切片表达式(slicing expression)
Python官方文档对切片语法的说明非常简洁:
A slicing selects a range of items in a sequence object (e.g., a string, tuple or list). Slicings may be used as expressions or as targets in assignment or del statements.
根据文档说明,切片语法分为两种:简单切片(simple_slicing)和扩展切片(extended_slicing),下面分别进行介绍。
>>> s = ['a', 'b', 'c', 'd', 'e', 'f'] >>> s[0 : len(s)] ## output: ['a', 'b', 'c', 'd', 'e', 'f'] >>> s[0 : -1] ## output: ['a', 'b', 'c', 'd', 'e'] >>> s[ : -1] ## output: ['a', 'b', 'c', 'd', 'e'] >>> s[2 : -1] ## output: ['c', 'd', 'e'] >>> s[-3 : -1] ## output: ['d', 'e'] >>> s[-3 : ] ## output: ['d', 'e', 'f'] >>> s[3 : 1] ## output: []
3. 扩展切片(extended_slicing)
扩展切片语法如下:
s[begin : end : stride]
与简单切片语法相比,扩展切片只是增加了第3个参数,即步长参数(英文资料中通常称为"stride"或"step")。
扩展切片语法引入的"stride"参数是个需要特别注意的参数,因为它的正/负取值将会影响切片操作对源序列s的访问方向,而这正是本文开始那几个示例可能引起Python新手困惑的原因。
其实规则很简单,说穿不值一文钱:
1) 当stride参数为正值(positive)时,表明切片操作从左至右(即正向)访问源序列s的元素,此时,若begin和end参数有缺省,则Python解释器默认将其设置为None。如s[0 : : 1]会被解释器当作s[0 : None : 1],此时,end实际取值要大于其有效索引范围的上限值,以保证切片操作能访问到源序列s从begin开始的所有元素(从左向右)。
2) 当stride参数为负值(negative)时,表明切片操作从右至左(即逆向)访问源序列s的元素,此时,若begin和end参数有缺省,则Python解释器默认将其设置为None。如s[-1 : : -1]会被解释器当作s[-1 : None : -1],此时,end实际取值要小于其有效索引范围的下限值,已保证切片操作能访问到源序列s从begin开始的所有元素(逆向,从右向左)。
3) 无论stride参数取正值还是负值,切片表达式的begin和end索引值需要保证在切片操作的访问方向上,从begin到end之间有元素,这样切片操作才能保证返回非空集。
通过本文第2节给出的Python内部对序列对象索引值约定示意图,应该可以很容易地理解这3条规则。
介绍到这里,本文开始处的那个示例输出结果的原因想必也很清楚了吧。
>>> s = 'this_is_a_test' >>> s[ : : -1] 'tset_a_si_siht' ## Q: 为何s被反转了? A: 步长参数-1表明逆向访问s >>> s[1 : 6 : -1] '' ## Q: 为何只得到个空串? A: 步长参数为负时,逆向访问,但begin与end间无元素,故返空串 >>> s[6 : 1 : -1] 'si_si' ## Q: 为何是这个结果? A: 逆向访问,切片访问到的元素正值索引范围为[2:6],故返'si_si'
备注:根据《Python核心编程》一书第6.1.2节的介绍,这里称为“扩展”是因为早期的Python解释器只支持不带步长参数的简单切片,带步长的切片操作是以Python扩展的方式实现的。事实上,目前的CPython解释器早就支持纯Python的带步长参数的切片操作,但作为历史名称,“扩展”一词被保留下来。
========================= EOF ======================
【Python笔记】剖析Python的切片(slicing)语法
原文地址:http://blog.csdn.net/slvher/article/details/44703185