Python 列表切片技巧,Python的列表对象有方便的切片特性。切片可被视为方括号索引语法的扩展,通常用于访问有序集合中某一范围的元素。例如,将一个大型列表对象分成几个较小的子列表。
来看一个例子,切片使用熟悉的[]
索引语法和如下[start:stop:step]
模式:
>>> lst = [1, 2, 3, 4, 5]
>>> lst
[1, 2, 3, 4, 5]
# lst[start:end:step]
>>> lst[1:3:1]
[2, 3]
[1:3:1]
索引返回从索引1到索引2的原始列表切片,步长为一个元素。为了避免多算一个元素的错误,需要记住切片计算方法是算头不算尾。因此[1:3:1]
切片的子列表是[2,3]
。
如果不提供步长,则默认为1:
>>> lst[1:3]
[2, 3]
步长(step)参数也称为步幅(stride),还可用来做其他有趣的事情。例如,可以创建一个间隔包含原列表元素的子列表:
>>> lst[::2]
[1, 3, 5]
很有趣吧!我喜欢称冒号分隔符:
为寿司操作符,因为这像是一个从侧面切开的美味太卷寿司(maki roll)。除了让人想到美食和访问列表范围之外,切片还有一些鲜为人知的应用。下面介绍更多有趣且有用的列表切片技巧。
除了刚才看到的使用切片步长来间隔选择列表中的元素,还有其他用法。比如[::-1]
切片会得到原始列表的逆序副本:
>>> numbers[::-1]
[5, 4, 3, 2, 1]
这里用::
让Python提供完整的列表,但将步长设置为-1
来从后到前遍历所有元素。这种方式很整洁,但在大多数情况下我仍然坚持使用list.reverse()
和内置的reverse()
函数来反转列表。
还有另一个列表切片技巧,即使用:
操作符清空列表中的所有元素,同时不会破坏列表对象本身。
这适用于在程序中有其他引用指向这个列表时清空列表。在这种情况下,通常不能用新的列表对象替换已有列表来清空列表,替换列表不会更新原列表的引用。此时“寿司操作符”就派上用场了:
>>> lst = [1, 2, 3, 4, 5]
>>> del lst[:]
>>> lst
[]
上面的操作删除了lst
中的所有元素,但保持列表对象本身不变。在Python 3中也可以使用lst.clear()
完成同样的工作,这种方式在某些情况下可读性更好。但要注意在Python 2中无法使用clear()
。
除了清空列表之外,切片还可以用来在不创建新列表对象的情况下替换列表中的所有元素,即手动快速清空列表然后重新填充元素:
>>> original_lst = lst
>>> lst[:] = [7, 8, 9]
>>> lst
[7, 8, 9]
>>> original_lst
[7, 8, 9]
>>> original_lst is lst
True
前面的示例中替换了列表中的所有元素,但并未销毁再重新创建列表本身。因此原始列表对象的旧引用仍然有效。
“寿司操作符”的另一个作用是创建现有列表的浅副本:
>>> copied_lst = lst[:]
>>> copied_lst
[7, 8, 9]
>>> copied_lst is lst
False
创建浅副本意味着只复制元素的结构,而不复制元素本身。两个列表中的每个元素都是相同的实例。
如果需要复制所有内容(包括元素),则需要创建列表的深副本。此时可以使用Python内置的copy
模块。
关键要点
-
“寿司操作符”不仅可用于选择列表中的元素的子列表,还可以用来清除、反转和复制列表。
-
但要小心,许多Python开发人员对这个功能不是非常了解,团队中的其他人可能难以维护用到这些特性的代码。