【问题标题】:Python list() vs list comprehension building speedPython list() 与列表理解构建速度
【发布时间】:2015-06-04 02:18:42
【问题描述】:

这很有趣; list() 强制迭代器获取实际列表比 [x for x in someList] 快得多(理解)。

这是真的还是我的测试太简单了? 下面是代码:

import time    

timer = time.clock()
for i in xrange(90):

    #localList = [x for x in xrange(1000000)]   #Very slow, took me 6.8s
    localList = list(xrange(1000000))           #Very fast, took me 0.9s

    print localList[999999] #make sure list is really evaluated.

print "Total time: ", time.clock() - timer

【问题讨论】:

  • Python 3.4 对于 10^6 列表,使用 timeit 提供 5.5s 和 3.6s。
  • @user5061:如果包装在一个函数中并使用本地变量,这里的时间会好很多。在 Python 3 中,列表推导式有自己的作用域(如生成器表达式),并且局部变量更快。

标签: python performance list list-comprehension python-2.x


【解决方案1】:

列表推导以 Python 字节码执行循环,就像常规的 for 循环一样。

list() 调用完全在 C 代码中迭代,这要快得多。

列表推导的字节码如下所示:

>>> import dis
>>> dis.dis(compile("[x for x in xrange(1000000)]", '<stdin>', 'exec'))
  1           0 BUILD_LIST               0
              3 LOAD_NAME                0 (xrange)
              6 LOAD_CONST               0 (1000000)
              9 CALL_FUNCTION            1
             12 GET_ITER            
        >>   13 FOR_ITER                12 (to 28)
             16 STORE_NAME               1 (x)
             19 LOAD_NAME                1 (x)
             22 LIST_APPEND              2
             25 JUMP_ABSOLUTE           13
        >>   28 POP_TOP             
             29 LOAD_CONST               1 (None)
             32 RETURN_VALUE        

&gt;&gt; 指针大致为您提供了正在执行的循环的边界,因此您有 100 万个 STORE_NAMELOAD_NAMELIST_APPEND 步骤要在 Python 字节码评估循环中执行。

另一方面,list() 只是通过使用 C API 直接从 xrange() 迭代中获取值进行对象迭代,它可以使用 xrange() 对象的长度来预分配列表对象而不是而不是动态增长。

【讨论】:

  • 这只是一个实现细节吗?编译器可以在任何时候以这种形式自动转换列表推导吗?
  • @KarolyHorvath:把它变成什么?
  • 到快速版本:到list(iterable) 形式(当然使用内置的list,以防它是本地定义的)。来自[v for v in iterable] 表单。
  • @KarolyHorvath:也许可以;我现在想不出为什么不能用list() 替换表单的原因。我确实经常看到这个错误(rows = [row for row in csvreader],或lines = [line for line in fileobj],等等)。我会看到将其发布到 python-ideas 列表中。
  • @user1777914: dict.fromkeys(someList, True).
猜你喜欢
  • 2020-11-09
  • 2019-10-26
  • 1970-01-01
  • 1970-01-01
  • 2014-09-01
  • 2023-03-29
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多