python复制列表时[:]和[::]之间有什么区别
前言
new=old[:]
Python老鸟都知道以上代码是什么意思。它复制列表old到new。它对于新手来说是种困惑而且应该避免使用这种方法。不幸的是[:]标记法被广泛使用,可能是Python程序员不知道更好的列表复制法吧。然而本文给大家介绍的是关于python复制列表时[:]和[::]之间有什么区别,下面来一起看看吧
我们可以(浅)使用[:]复制列表:
l=[1,2,3] z1=l[:]
我们也可以(浅)使用[::]复制它:
z2=[::]
现在z1==z2将为True.在ExplainPython'sslicenotation阅读答案后,我了解这些图片的工作原理.
但是,我的问题是这两个内部是否有区别?在复制中比其他效率更高,还是做完全相同的事情?
最佳答案
他们之间绝对没有区别,至少在Python3中.如果你愿意,可以使用dis.dis来检查每个这些使用的字节码:
l=[1,2,3,4]
针对l[:]发出的字节码:
fromdisimportdis dis('l[:]') 10LOAD_NAME0(l) 3LOAD_CONST0(None) 6LOAD_CONST0(None) 9BUILD_SLICE2 12BINARY_SUBSCR 13RETURN_VALUE
而为l[::]发送的字节码:
dis('l[::]') 10LOAD_NAME0(l) 3LOAD_CONST0(None) 6LOAD_CONST0(None) 9BUILD_SLICE2 12BINARY_SUBSCR 13RETURN_VALUE
你可以看到,它们完全一样.对于构建切片(BUILD_SLICE)的起始和停止值都加载一些无(两个LOAD_CONSTS),并应用它.NONE是StandardTypehierarchy中切片文档中所述的默认值:
Specialread-onlyattributes:startisthelowerbound;stopistheupperbound;stepisthestepvalue;eachisNoneifomitted.Theseattributescanhaveanytype.
使用[:],它的键击少.
实际上有趣的是,在Python2.x中,生成的字节代码是不同的,由于l[:]的命令较少,可能会稍微更高效:
>>>deffoo(): ...l[:] ... >>>dis(foo) 20LOAD_GLOBAL0(l) 3SLICE+0 4POP_TOP 5LOAD_CONST0(None) 8RETURN_VALUE
而对于l[::]:
>>>deffoo2(): ...l[::] ... >>>dis(foo2) 20LOAD_GLOBAL0(l) 3LOAD_CONST0(None) 6LOAD_CONST0(None) 9LOAD_CONST0(None) 12BUILD_SLICE3 15BINARY_SUBSCR 16POP_TOP 17LOAD_CONST0(None) 20RETURN_VALUE
即使我没有定时这些(我不会,差异应该很小)看起来,由于只需要更少的指示,l[:]可能稍微好一点.
这种相似性当然不存在于列表中;它适用于Python中的所有序列:
#Note:theBytecodeclassexistsinPy>3.4 >>>fromdisimportBytecode >>> >>>Bytecode('(1,2,3)[:]').dis()==Bytecode('(1,2,3)[::]').dis() True >>>Bytecode('"string"[:]').dis()==Bytecode('"string"[::]').dis() True
对于别人也是如此.
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。