Python列表理解很昂贵 [英] Python list comprehension expensive

查看:82
本文介绍了Python列表理解很昂贵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试查找列表理解的效率,但是它看起来比普通的函数操作更昂贵.有人可以解释吗?

Im trying to find the effeciency of list comprehension but it look like its more expensive than a normal function operation. Can someone explain?

def squares(values):
    lst = []
    for x in range(values):
        lst.append(x*x)
    return lst

def main():
    t = timeit.Timer(stmt="lst = [x*x for x in range(10)]")
    print t.timeit()
    t = timeit.Timer(stmt="squares",setup="from __main__ import squares")
    print t.timeit()

    lst = [x*x for x in range(10)]
    print lst
    print squares(10)



----Output:---
2.4147507644
0.0284455255965
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

对于相同的输出,与列表理解相比,普通函数的计算时间要短得多.

For the same output, the normal function calculates in very less time compared to the list comprehension.

我认为列表理解更有效.

I thought the list comprehension is more effecient.

推荐答案

您永远不会调用您的squares函数,因此它什么也没做.

You are never calling your squares function, so it is not doing anything.

列表理解 实际上更快:

>>> import timeit
>>> def squares(values):
...     lst = []
...     for x in range(values):
...         lst.append(x*x)
...     return lst
... 
>>> def squares_comp(values):
...     return [x*x for x in range(values)]
... 
>>> timeit.timeit('f(10)', 'from __main__ import squares as f')
3.9415171146392822
>>> timeit.timeit('f(10)', 'from __main__ import squares_comp as f')
2.3243820667266846

如果使用dis模块查看每个功能的字节码,则可以了解原因:

If you use the dis module to look at the bytecode for each function, you can see why:

>>> import dis
>>> dis.dis(squares)
  2           0 BUILD_LIST               0
              3 STORE_FAST               1 (lst)

  3           6 SETUP_LOOP              37 (to 46)
              9 LOAD_GLOBAL              0 (range)
             12 LOAD_FAST                0 (values)
             15 CALL_FUNCTION            1
             18 GET_ITER            
        >>   19 FOR_ITER                23 (to 45)
             22 STORE_FAST               2 (x)

  4          25 LOAD_FAST                1 (lst)
             28 LOAD_ATTR                1 (append)
             31 LOAD_FAST                2 (x)
             34 LOAD_FAST                2 (x)
             37 BINARY_MULTIPLY     
             38 CALL_FUNCTION            1
             41 POP_TOP             
             42 JUMP_ABSOLUTE           19
        >>   45 POP_BLOCK           

  5     >>   46 LOAD_FAST                1 (lst)
             49 RETURN_VALUE        
>>> dis.dis(squares_comp)
  2           0 BUILD_LIST               0
              3 LOAD_GLOBAL              0 (range)
              6 LOAD_FAST                0 (values)
              9 CALL_FUNCTION            1
             12 GET_ITER            
        >>   13 FOR_ITER                16 (to 32)
             16 STORE_FAST               1 (x)
             19 LOAD_FAST                1 (x)
             22 LOAD_FAST                1 (x)
             25 BINARY_MULTIPLY     
             26 LIST_APPEND              2
             29 JUMP_ABSOLUTE           13
        >>   32 RETURN_VALUE        

squares函数在每次迭代中查找列表的.append()方法,并对其进行调用. .append()函数必须在每次调用时将列表增加一个元素.

The squares function looks up the .append() method of the list in each iteration, and calls it. The .append() function has to grow the list by one element each time it is called.

另一方面,列表理解不必完成这项工作.取而代之的是,python使用LIST_APPEND字节码,该字节码使用C API将新元素添加到列表中,而无需执行查找和对该函数的python调用.

The list comprehension on the other hand doesn't have to do that work. Instead, python uses the LIST_APPEND bytecode, which uses the C API to append a new element to the list, without having to do the lookup and a python call to the function.

这篇关于Python列表理解很昂贵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆