Contents
30.2.2. 不要在切片里同时指定起止下标与步进¶
Python还有一种特殊的步长切片形式,即somelist[start:end:stride]。这种形式会在每n个元素里面选取一个,这样很容易就能把奇数位置上的元素与偶数位置上的元素分别通过x[::2]与x[1::2]选取出来。
In [26]: x = ['red', 'orange', 'yellow', 'green', 'blue', 'purple']
...: odds = x[::2] # 从下标0开始,每2个元素取一个(隔1个取1个)
...: evens = x[1::2] # 从下标1开始,每2个元素取一个
...: print(odds)
...: print(evens)
...:
...:
['red', 'yellow', 'blue']
['orange', 'green', 'purple']
Python里面有个技巧,把-1当成步长对bytes类型的字符串做切片,这样就能将字符串反转过来。
In [27]: x = b'mongoose'
...: y = x[::-1]
...:
...:
In [28]: y
Out[28]: b'esoognom'
Unicode形式的字符串也可以这样反转
In [29]: x = '月饼'
...: y = x[::-1]
...: y
...:
...:
Out[29]: '饼月
如果把这种字符串编码成UTF-8标准的字节数据,就会报错
使用起止下标与步长会让切片很难懂。 为了避免这个问题,建议大家不要把起止下标和步长同时写在切片里。 如果必须指定步长,那么尽量采用正数,而且要把起止下标都留空。即便必须同时使用步长值与起止下标,也应该考虑分成两次来写。
y = x[::2] # ['a', 'c', 'e', 'g']
z = y[1:-1] # ['c', 'e']
要点:
同时指定切片的起止下标与步进值理解起来会很困难。
如果要指定步进值,那就省略起止下标,而且最好采用正数作为步进值,尽量别用负数。
不要把起始位置、终止位置与步进值全都写在同一个切片操作里。如果必须同时使用这三项指标,那就分两次来做(其中一次隔位选取,另一次做切割),也可以改用itertools内置模块里的islice方法。