除了基本的切片操作之外,Python还提供了somelist[start🔚stride]形式的写法,以实现步进式切割,也就是从每n个元素里取1个出来,例如,可以指定步进值,把列表中位于偶数索引处和奇数索引处的元素分成两组:
a = ['red', 'orange', 'yellow', 'green', 'blue', 'purple']
odds = a[::2]
evens = a[1::2]
print(odds)
print(evens)
输出结果:
['red', 'yellow', 'blue']
['orange', 'green', 'purple']
python中有一种觉的技巧,能够把序列反转
x='mongoose'
y = x[::-1]
print(y)
输出结果:
esoognom
这种反转也支持bytes类型。
a= ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'g']
a[::2] # ['a','e','c','a']
a[::-2] # ['h', 'f', 'd', 'b']
从上面的例子可以看出,::2表示从头部开始,第两个元素取一个,::-2表示从尾部向前,每两个元素取一个。
那么a[2::2] a[-2::-2] a[2:2:-2]又各表示什么意思呢 ?
如果指定了stride,那么代码可能会变得相当费解。在一对括号中写上3个数字显得太过拥挤,从而使代码难以阅读。这种写法使得start和end的含义变得模糊,尤其是stride为负值时。
为了解决这种问题,我们不应该把 stride 与 start 和 end 写在一起。如果非要用stride,那就尽量用正值,同时活力start和end索引。如果一定要三者一起用,那么可以考虑做两次切片,比如先用start和end切片,再指定stride切片。
如果需切片的列表太长,或者系统内存太小,或者执行时间要求很高,以致不能采用两段切割法,那么就应考虑使用python的内置itertools模块,该模块中有一个islide方法。
要点:
- 既有start和end,又有stride的切割操作,可能会令人费解。
- 尽量使用stride为正数,且不带start和end索引的切割操作。尽量避免用负数做stride.
- 在同一个切片操作内,不要同时使用start、end和stride。如果确实需要执行这种操作,那就考虑将其拆解为两条赋值语句,其中一条做范围切割,另一条做步进切割,或考虑使用内置itertools模块中的islice.