old = [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
以下两行之间有什么区别(如果有的话)?
new = old[:]
new = list(old)
Run Code Online (Sandbox Code Playgroud)
更新我已经接受了ubershmekel的答案,但后来我学到了一个有趣的事实:[:]小列表(10个元素)list()更快,但更大的列表(100000个元素)更快.
~$ python -S -mtimeit -s "a = list(range(10))" "a[:]"
1000000 loops, best of 3: 0.198 usec per loop
~$ python -S -mtimeit -s "a = list(range(10))" "list(a)"
1000000 loops, best of 3: 0.453 usec per loop
~$ python -S -mtimeit -s "a = list(range(100000))" "a[:]"
1000 loops, best of 3: 675 usec per loop
~$ python -S -mtimeit -s "a = list(range(100000))" "list(a)"
1000 loops, best of 3: 664 usec per loop
Run Code Online (Sandbox Code Playgroud)
是的,有一点不同.最近在这篇博客文章解释了可读性差异后,在/ r/python上对此进行了讨论,这种差异不适用于生成器并保持与原始类型相同的类型.[:]
从技术上讲,你会得到同样的东西 - 一个仍然指向相同对象的全新列表.选择你喜欢的任何一个(虽然[:]有点快).就个人而言,我同意list(old)更具可读性的博客文章.
要回答有关具体差异的评论,请在python 3.2中:
>>> import dis
>>> def colon(x):
... return x[:]
...
>>> def new_list(x):
... return list(x)
...
>>>
>>> dis.dis(colon)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 0 (None)
6 LOAD_CONST 0 (None)
9 BUILD_SLICE 2
12 BINARY_SUBSCR
13 RETURN_VALUE
>>> dis.dis(new_list)
2 0 LOAD_GLOBAL 0 (list)
3 LOAD_FAST 0 (x)
6 CALL_FUNCTION 1
9 RETURN_VALUE
>>>
Run Code Online (Sandbox Code Playgroud)
为什么list(old)我认为更慢是因为切片机制不需要在列表构造函数上使用"LOAD_GLOBAL"和"CALL_FUNCTION",整个操作在C中处理.
如果old不是列表,则旧的[:]将是旧的(与元组或字符串相同)容器中的旧元素,而list(旧)将是具有相同元素的列表.
即如果旧的是字符串'foo',则旧的[:]将是字符串'foo',而list(old)将是列表['f','o','o'].