Python切片
在Python中,切片(slice)是对序列型对象(如list
, string
, tuple
)的一种高级索引方法。普通索引只取出序列中一个下标对应的元素,而切片取出序列中一个范围对应的元素,这里的范围不是狭义上的连续片段。下面的代码初步展示了切片索引的力量。
>>> a=list(range(10))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[:5]
[0, 1, 2, 3, 4]
>>> a[2:8]
[2, 3, 4, 5, 6, 7]
>>> a[::2]
[0, 2, 4, 6, 8]
>>> a[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
切片语法
扩展切片指的是这样的切片形式:a[start:stop:step]
,其中step
是一个非零整数,即比简单切片多了调整步长的功能,此时切片的行为可概括为:从start
对应的位置出发,以step
为步长索引序列,直至越过stop
对应的位置,且不包括stop
本身。事实上,简单切片就是step
=1的扩展切片的特殊情况。需要详细解释的是step
分别为正数和负数的两种情况。
简单切片
简单切片指的是这样的切片形式:a[start:stop]
,其行为是得到下标在这样一个前闭后开区间范围内的元素,其中start
和stop
为负数时,简单看作是负数下标对应的位置即可:
>>> a=list(range(10))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[2:3]
[2]
>>> a[5:9]
[5, 6, 7, 8]
>>> a[5:-1]
[5, 6, 7, 8]
>>> a[-5:9]
[5, 6, 7, 8]
>>> a[-5:-1]
[5, 6, 7, 8]
step为正数
当step
为正数时,切片行为很容易理解,start
和stop
的截断和缺省规则也与简单切片完全一致:
>>> a=list(range(10))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[0:5:1]
[0, 1, 2, 3, 4]
>>> a[0:5:2]
[0, 2, 4]
>>> a[0:5:3]
[0, 3]
>>> a[::2]
[0, 2, 4, 6, 8]
>>> a[:-2:2]
[0, 2, 4, 6]
>>> a[4:-2:2]
[4, 6]
>>>
step为负数
当step
为负数时,切片将其解释为从start
出发以步长|step|
逆序索引序列,此时,start
和stop
的截断依然遵循前述规则,但缺省发生一点变化,因为我们说过,在缺省的情况下,Python的行为是尽可能取最大区间,此时访问是逆序的,start
应尽量取大,stop
应尽量取小,才能保证区间最大,因此:
按照扩充索引范围的观点,
start
的缺省值是无穷大(),stop
的缺省值是无穷小()
>>> a=list(range(10))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[0:5:-1]
[]
>>> a[0:5:-2]
[]
>>> a[0:5:-3]
[]
>>> a[::-2]
[9, 7, 5, 3, 1]
>>> a[:-2:-2]
[9]
>>> a[4:-2:-2]
[]
>>> a[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>>
缺省情况
为了深入理解step
为缺省情况,来看下面一个示例:
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[0::-1]
[0]
>>> a[0:len(a):-1]
[]
为什么有len(a)和省略len(a)结果会不一样?
根据上面的描述,可以做如下解释:
start
、stop
、step
(step缺省值为1)都是可以缺省的,在缺省的情况下,Python的行为是尽可能取最大区间,具体来说:
- 当step>0时,按照扩充索引范围的观点,
start
的缺省值是无穷小(),stop
的缺省值是无穷大(),才能保证区间最大- 当step<0时,按照扩充索引范围的观点,
start
的缺省值是无穷大(),stop
的缺省值是无穷小(),才能保证区间最大- 当step=0时,报错:ValueError: slice step cannot be zero
提醒
当start或stop超出有效索引范围时,切片操作不会抛出异常,而是进行截断。可以这样去理解截断机制:我们假象把索引范围扩充到全体整数,只不过小于或大于的区域对应空元素,在这个扩充后的数轴上进行切片,只需把最终结果中的所有空元素忽略即可。
来看几个具体的例子:
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[-100:5]
[0, 1, 2, 3, 4]
>>> a[5:100]
[5, 6, 7, 8, 9]
>>> a[-100:100]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[100:1000]
[]
另外,如果start的位置比stop还靠后怎么办?Python还是不会抛出异常,而是直接返回空序列:
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[6:5]
[]
slice()函数
实例
创建一个元组和一个 slice 对象。使用 slice 对象仅获取元组的前两项:
>>> a = ("a", "b", "c", "d", "e", "f", "g", "h")
>>> x = slice(2)
>>> x
slice(None, 2, None)
>>> a[x]
('a', 'b')
>>>
定义和用法
slice() 函数返回 slice 对象(切片)。
slice 对象用于指定如何对序列进行裁切。您可以指定在哪里开始裁切以及在哪里结束裁切。您还可以指定步进,例如只切每隔一个项目。
语法
slice(start, end, step)
参数值
参数|描述 start|可选。整数,指定在哪个位置开始裁切。默认为 0。 end|可选。整数,指定在哪个位置结束裁切。 step|可选。整数,指定裁切的步进值。默认为 1。
更多实例
【例】创建一个元组和一个切片对象,并返回结果:
>>> a = ("a", "b", "c", "d", "e", "f", "g", "h")
>>> x = slice(2)
>>> x
slice(None, 2, None)
>>> a[x]
('a', 'b')
>>> x = slice(3,5)
>>> x
slice(3, 5, None)
>>> a[x]
('d', 'e')
>>> x = slice(3,5,-1)
>>> a[x]
()
>>> x = slice(3,5,2)
>>> a[x]
('d',)
>>>