Python中列表切片[:]与[::]的区别解析
本文深入探讨Python中列表切片[:]和[::]在复制列表时的异同。在Python 3中,两者生成的字节码完全一致,无性能差异;但在Python 2.x中,[:]因指令更少而略高效。文章通过dis模块分析字节码,并指出该特性适用于所有序列类型,建议开发者根据版本选择写法。
前言
new = old[:]
经验丰富的Python开发者通常清楚上述代码的含义:它将列表old浅拷贝至new。尽管这种方法对初学者而言可能令人困惑且不建议使用,但[:]切片法依然被广泛采用,部分原因可能是许多Python程序员尚未了解更优的列表复制方式。本文将详细解析Python在复制列表时[:]与[::]之间的具体区别,供读者参考。
我们可以使用[:]对列表进行浅拷贝:
l = [1, 2, 3] z1 = l[:]
同样,我们也可以使用[::]对其进行浅拷贝:
z2 = [::]
此时,表达式z1 == z2的结果为True。在查阅《Explain Python's slice notation》一文后,我理解了这些切片操作的工作原理。
然而,我的核心疑问在于:这两种写法内部是否存在差异?在复制操作中,哪一种效率更高,或者它们是否执行完全相同的逻辑?
最佳答案
在Python 3中,两者之间绝对没有区别。如果感兴趣,可以使用dis.dis函数检查它们生成的字节码:
l = [1, 2, 3, 4]
针对表达式l[:]发出的字节码如下:
from dis import dis
dis('l[:]')
1 0 LOAD_NAME 0 (l)
3 LOAD_CONST 0 (None)
6 LOAD_CONST 0 (None)
9 BUILD_SLICE 2
12 BINARY_SUBSCR
13 RETURN_VALUE
而针对表达式l[::]发出的字节码如下:
dis('l[::]')
1 0 LOAD_NAME 0 (l)
3 LOAD_CONST 0 (None)
6 LOAD_CONST 0 (None)
9 BUILD_SLICE 2
12 BINARY_SUBSCR
13 RETURN_VALUE
从输出可见,两者完全一致。对于构建切片(BUILD_SLICE)操作,起始值和停止值均加载了None(通过两个LOAD_CONST指令)。None是标准类型层次结构中切片文档所定义的默认值:
Special read-only attributes: start is the lower bound; stop is the upper bound; step is the step value; each is None if omitted. These attributes can have any type.
从代码书写的角度来看,使用[:]所需的击键次数更少。
有趣的是,在Python 2.x版本中,生成的字节码存在差异。由于l[:]涉及的指令较少,它可能会稍微高效一些:
>>> def foo():
... l[:]
...
>>> dis(foo)
2 0 LOAD_GLOBAL 0 (l)
3 SLICE+0
4 POP_TOP
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
而对于l[::]的情况:
>>> def foo2():
... l[::]
...
>>> dis(foo2)
2 0 LOAD_GLOBAL 0 (l)
3 LOAD_CONST 0 (None)
6 LOAD_CONST 0 (None)
9 LOAD_CONST 0 (None)
12 BUILD_SLICE 3
15 BINARY_SUBSCR
16 POP_TOP
17 LOAD_CONST 0 (None)
20 RETURN_VALUE
尽管我未对这两种情况进行严格计时(差异预期极小),但仅从指令数量来看,l[:]似乎略占优势。
这种相似性不仅限于列表,它同样适用于Python中的所有序列类型:
# Note: the Bytecode class exists in Py > 3.4
>>> from dis import Bytecode
>>>
>>> Bytecode('(1, 2, 3)[:]').dis() == Bytecode('(1, 2, 3)[::]').dis()
True
>>> Bytecode('"string"[:]').dis() == Bytecode('"string"[::]').dis()
True
其他序列类型也是如此。
总结
以上就是本文的全部内容,希望本文的解析对大家的学习或工作具有一定的参考价值。如有疑问,欢迎留言交流,感谢大家对本站的支持。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









