2014-09-01 79 views
1

我在编写一些Python代码时偶然发现了令我感到意外的事情。我正在考虑复制一个列表,然后再添加一个元素重复的方法有两种:为什么列出`my_list + ['foo']`比`new_list = list(my_list)快; Python中的new_list.append('foo')`?

# I thought this would be clean-looking but slow since it creates an extra one element list, ['foo'] 
mylist = range(4) 
newlist_0 = mylist + ['foo'] 
print newlist_0 # [0, 1, 2, 3, 'foo'] 

# I thought this would be faster 
newlist_1 = list(mylist) 
newlist_1.append('foo') 
print newlist_1 # [0, 1, 2, 3, 'foo'] 

令人惊讶的是第一种方式,不仅好看,而且速度更快。我跑:

import timeit 
for stmt in ['newlist_0 = mylist + ["foo"]', 'newlist_1 = list(mylist); newlist_1.append("foo")']: 
    print "For statement {:50} timeit results are {}".format(stmt, timeit.repeat(setup='mylist = range(4)', stmt=stmt)) 

,并得到这样的输出:

For statement newlist_0 = mylist + ["foo"]      timeit results are [0.29012012481689453, 0.3021109104156494, 0.32175779342651367] 
For statement newlist_1 = list(mylist); newlist_1.append("foo") timeit results are [0.39945101737976074, 0.39692091941833496, 0.38529205322265625] 

暂时我无意中发现this question讨论的事实,list(lst)lst[:]慢用于复制的列表,但切换到使用[:]复制MYLIST没有按什么都不会改变。

+2

函数调用开销 – wim 2014-09-01 18:06:03

+0

@wim,那么我是否正确地推断,那么''''''''和''''''''''都不涉及函数调用,但是'append'呢? – kuzzooroo 2014-09-01 18:18:48

回答

2

让我们来看看反汇编。你的第一种方法看起来像这样在Python 2.7字节码:

  0 LOAD_FAST    0 (mylist) 
      3 LOAD_CONST    1 ('foo') 
      6 BUILD_LIST    1 
      9 BINARY_ADD   

第二种方法是这样的:

  0 LOAD_GLOBAL    0 (list) 
      3 LOAD_FAST    0 (mylist) 
      6 CALL_FUNCTION   1 
      9 STORE_FAST    1 (newlist_1) 

     12 LOAD_FAST    1 (newlist_1) 
     15 LOAD_ATTR    1 (append) 
     18 LOAD_CONST    1 ('foo') 
     21 CALL_FUNCTION   1 

有几件事情,这将使后者较慢的基础上,拆卸的比较:

  1. list必须从全局名称空间加载。

  2. append必须从列表对象中加载。

  3. 您支付两次通话费用而非一次性费用。

简短的回答就是,Python字节码,具有存储的短名单像['foo']和做二元运算的非常简洁和有效的方式。

+0

你用什么来拆卸?如果我运行'def f1():newlist_0 = mylist + ['foo']'然后是'dis.dis(f1)',我得到7行输出,并且不能通过函数搞乱它。 – kuzzooroo 2014-09-01 18:34:13

+0

我使用'dis'模块并在函数中包装了一些东西。我的'f1'不同,因为我'返回mylist + ['foo']'。 – 2014-09-01 18:40:44

相关问题