在学习深度学习的过程中,由于神经网络算法要用到向量化的方法来加速计算,因此时常用到Python中的列表数据结构,切片是列表的常用操作,最近发现初学的时候对切片如何截取列表常常遗忘和混淆,这里用一篇手记简单总结一下。
假设a是一个一维的列表,先给出一个基本的公式:a[start:end:step],
其中start是第一个截取的元素,end是第一个不截取的元素,step是截取的步长,缺省状态下默认是1,也就是正向逐个截取。
上面说的还比较抽象,下面用具体的代码来展示:
a = [1, 2, 3, 4, 5, 6]
a[0:3] # [1, 2, 3]
a[:3] # [1, 2, 3]
a[1:5] # [2, 3, 4, 5]
a[1:6] # [2, 3, 4, 5, 6]
a[1:7] # [2, 3, 4, 5, 6]
a[1:] # [2, 3, 4, 5, 6]
a[::2] # [1, 3, 5]
a[:] # [1, 2, 3, 4, 5]
上面的代码演示了几种边缘情况,也是比较重要的情况:
start缺省时默认是0,也就是从头开始;
end缺省时默认是取到最后一个元素,取到最后一个元素的另一种方法是给end赋一个比最后一个元素的index更大的值
start和end都缺省时表示取整个列表
上面的例子里,start、end和step都为正,而这三个值也可以为负,先来看start和end为负,step依然为正的情况:
a = [1, 2, 3, 4, 5, 6]
a[-1] # 6
a[-2:] # [5, 6]
a[:-2] # [1, 2, 3, 4]
a[-2:-4] # []
a[-4:-2] # [3, 4]
在start和end为负时,是从列表的反方向来索引的,-1代表列表的倒数第一个元素,-2代表倒数第二个元素,依此类推。需要注意的是,在step为正时,依然是正向截取列表,因此上面的a[-2:-4]得到的是空列表,因为从正向来看,倒数第二个元素在倒数第四个元素的后面。在正向截取列表时,start的索引位置必须在end的索引位置的前面。
最后来看一下最不容易理解的step为负的情况,step为负时是反向截取列表的,还是先看例子,再具体讲解:
a = [1, 2, 3, 4, 5, 6]
a[:-3:-1] # [6, 5]
a[1::-1] # [2, 1]
a[-2:-3:-1] # [5]
a[-4:-3:-1] # []
a[1:4:-1] # []
a[1:-1:-1] # []
可以看到,step为负时,start的索引位置必须在end的索引位置的后面,否则只能得到空列表,这正是因为step为负时是反向截取列表的。此时,start在缺省状态下默认为-1,也就是从列表倒数第一个元素开始截取,end在缺省状态下默认截取到第一个元素。
以上是列表截取的基本知识,可以看到,列表截取时,经常用到冒号。
除了冒号,在处理Numpy数组时,我还遇到过省略号,常用在多维数组里。
假设b是一个三维的数组,则有:b[...,None] = b[:,:,None],文字上我暂时没有想到如何描述省略号的作用比较好,不过如果能看懂前面一小段代码,就能理解省略号的作用了,可以先简单理解为遍历除None以外的剩余维度。在后面某些项目代码的实际例子里我会进一步解释。
总结
上面简单讲了一点Python中列表和Numpy中N维数组的切片方法,关于Python列表和Numpy N维数组的切片和索引还有许多方法还是需要在实践中去总结和理解,后续如果有值得记录的我会再更新。
参考资料
本作品采用知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。要查看该许可协议,可访问 http://creativecommons.org/licenses/by-nc-sa/4.0/ 或者写信到 Creative Commons, PO Box 1866, Mountain View, CA 94042, USA。