列表理解优化

5 python list-comprehension list python-2.7

我设法将 8 行代码转换为 2 行。

第一个列表理解获取文件夹,第二个列表理解获取特定过滤器的文件:

hideTheseFolders=[".thumb",".mayaSwatches","RECYCLER","$AVG"]
fileFilters=["ma","jpg","png","mb",'iff','tga','tif']
newLst=[]
import os
locationTxt="E:\box\scripts"
[newLst.append(each) for each in os.listdir(locationTxt)  if os.path.isdir(os.path.join(locationTxt,each)) and each not in hideTheseFolders]
[newLst.append(os.path.basename(os.path.join(locationTxt,each))) for nfile in fileFilters for each in os.listdir(locationTxt) if each.endswith(nfile)]
Run Code Online (Sandbox Code Playgroud)

现在,在上面的代码中,最后两行正在从 的同一目录中查找locationTxt,这意味着可能有一种方法可以合并最后两行。有什么建议么?

Ben*_*son 3

列表推导式不是一种优化技术。当 Python 编译器看到列表推导式时,它会将其分解为 for 循环。看字节码13( FOR_ITER):

In [1]: from dis import dis

In [2]: code = "[i for i in xrange(100)]"

In [3]: dis(compile(code, '', 'single'))
  1           0 BUILD_LIST               0
              3 LOAD_NAME                0 (xrange)
              6 LOAD_CONST               0 (100)
              9 CALL_FUNCTION            1
             12 GET_ITER            
        >>   13 FOR_ITER                12 (to 28)
             16 STORE_NAME               1 (i)
             19 LOAD_NAME                1 (i)
             22 LIST_APPEND              2
             25 JUMP_ABSOLUTE           13
        >>   28 POP_TOP             
             29 LOAD_CONST               1 (None)
             32 RETURN_VALUE      
Run Code Online (Sandbox Code Playgroud)

列表推导式与 for 循环相同的事实也可以通过计时来看出。在这种情况下,for 循环实际上稍微(但不明显)更快:

In [4]: %timeit l = [i for i in xrange(100)]
100000 loops, best of 3: 13.6 us per loop

In [5]: %%timeit l = []; app = l.append  # optimise out the attribute lookup for a fairer test
   ...: for i in xrange(100):
   ...:     app(i)
   ...: 
100000 loops, best of 3: 11.9 us per loop  #  insignificant difference. Run it yourself and you might get it the other way around
Run Code Online (Sandbox Code Playgroud)

因此,您可以将任何给定的列表推导式编写为 for 循环,从而对性能影响最小(实际上,由于属性查找,通常会存在很小的差异),并且通常会带来显着的可读性优势。特别是,具有副作用的循环不应为列表推导式。您也不应该使用包含两个以上for关键字的列表推导式,或者使一行长度超过 70 个字符左右的列表推导式。这些不是硬性规则,只是编写可读代码的启发式方法。

不要误会我的意思,列表推导式非常有用,并且通常比等效的 for 循环和附加更清晰、更简单和更简洁。但他们不应该被这样滥用。