前言
1
|
new = old[:] |
Python老鸟都知道以上代码是什么意思。它复制列表old到new。它对于新手来说是种困惑而且应该避免使用这种方法。不幸的是[:]标记法被广泛使用,可能是Python程序员不知道更好的列表复制法吧。然而本文给大家介绍的是关于python复制列表时[:]和[::]之间有什么区别,下面来一起看看吧
我们可以(浅)使用[:]复制列表:
1
2
|
l = [ 1 , 2 , 3 ] z1 = l[:] |
我们也可以(浅)使用[::]复制它:
1
|
z2 = [::] |
现在z1 == z2将为True.在Explain Python's slice notation阅读答案后,我了解这些图片的工作原理.
但是,我的问题是这两个内部是否有区别?在复制中比其他效率更高,还是做完全相同的事情?
最佳答案
他们之间绝对没有区别,至少在Python 3中.如果你愿意,可以使用dis.dis来检查每个这些使用的字节码:
1
|
l = [ 1 , 2 , 3 , 4 ] |
针对l [:]发出的字节码:
1
2
3
4
5
6
7
8
|
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 [::]发送的字节码:
1
2
3
4
5
6
7
|
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)的起始和停止值都加载一些无(两个LOAD_CONSTS),并应用它. NONE是Standard Type hierarchy中切片文档中所述的默认值:
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 [:]的命令较少,可能会稍微更高效:
1
2
3
4
5
6
7
8
9
|
>>> 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 [::]:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
>>> 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中的所有序列:
1
2
3
4
5
6
7
|
# 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 |
对于别人也是如此.
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:https://codeday.me/bug/20181015/290913.html