Python 切片

切片远比你想象的强大。你常见的惯用法可能是 list[start:stop:step],但事实上 Python 支持多维切片,也就是 [i, j],它会作为元组传入。之所以 Python 原生库很少见到多维切片,是因为基本所有序列都是一维的(memoryview 有可能不是),而对于 numpy 来说,它就可以通过多维切片来进行更方便的处理,比如:

1
array[3:, :3]

切片赋值

可变序列(如列表)的切片可以被同一种序列的内容替换,这也是相当方便的处理。

1
2
3
list = [1, 2, 3, 4, 5]
list[2:] = [114514]
# list 变为 [1, 2, 114514]

使用 slice 对象

序列的切片实际上是使用了 slice 函数,list[:] 等同于 list[slice(None, None)]

这有什么好处呢?好处就是你可以对切片进行命名。比如对于比较规整的字符串,你可以给一个专门切名字的切片命名为:

1
name = slice(None, 10)

调用时只需使用 list[name] 就可以完成切片,大大增加了可读性。

注意嵌套列表的构建

对于嵌套列表,需要注意的是,最好不要使用 * 来复制嵌套列表,而应该使用列表推导式,以防止内部嵌套的列表指向的是同一个列表导致的错误。

例如 [[[], []], [[], []]] 就是一个需要预防这种问题的嵌套列表——如果用乘法构造类似结构,很容易让子列表共享同一引用,造成意外修改。