我设法将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)]
现在在上面的代码中,最后两行是从locationTxt查看同一目录,这意味着可能有一种方法可以合并最后两行.有什么建议?
最佳答案 列表推导不是优化技术.当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
列表理解与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
因此,您可以将任何给定的列表推导编写为具有最小性能命中的for循环(实际上,由于属性查找通常存在很小的差异),并且通常具有显着的可读性益处.特别是,不应将具有副作用的循环写为列表推导.你也不应该使用大于2的关键字列表推导,或者使得一行超过70个字符左右的列表推导.这些不是硬性规则,只是用于编写可读代码的启发式方法.
不要误解我的意思,列表推导非常有用,并且通常比等效的for-loop-and-append更清晰,更简单,更简洁.但他们不应该以这种方式被滥用.