栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

列表理解是Python 3中`list(generator expression)`的语法糖吗?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

列表理解是Python 3中`list(generator expression)`的语法糖吗?

两者的工作方式不同。该列表理解的版本需要特殊的字节码的优势,

LIST_APPEND
这就要求
PyList_Append
直接给我们。因此,它避免了
list.append
在Python级别进行属性查找和函数调用。

>>> def func_lc():    [x**2 for x in y]...>>> dis.dis(func_lc)  20 LOAD_ConST    1 (<pre object <listcomp> at 0x10d3c6780, file "<ipython-input-42-ead395105775>", line 2>)   3 LOAD_ConST    2 ('func_lc.<locals>.<listcomp>')   6 MAKE_FUNCTION 0   9 LOAD_GLOBAL   0 (y)  12 GET_ITER  13 CALL_FUNCTION 1 (1 positional, 0 keyword pair)  16 POP_TOP  17 LOAD_ConST    0 (None)  20 RETURN_VALUE>>> lc_object = list(dis.get_instructions(func_lc))[0].argval>>> lc_object<pre object <listcomp> at 0x10d3c6780, file "<ipython-input-42-ead395105775>", line 2>>>> dis.dis(lc_object)  20 BUILD_LIST    0   3 LOAD_FAST     0 (.0)        >>    6 FOR_ITER     16 (to 25)   9 STORE_FAST    1 (x)  12 LOAD_FAST     1 (x)  15 LOAD_ConST    0 (2)  18 BINARY_POWER  19 LIST_APPEND   2  22 JUMP_ABSOLUTE 6        >>   25 RETURN_VALUE

另一方面,

list()
版本仅将生成器对象传递给list的
__init__
方法,然后在
extend
内部调用其方法。由于对象不是列表或元组,因此CPython首先获取其迭代器,然后简单地将项目添加到列表中,直到迭代器用尽:

>>> def func_ge():    list(x**2 for x in y)...>>> dis.dis(func_ge)  20 LOAD_GLOBAL   0 (list)   3 LOAD_ConST    1 (<pre object <genexpr> at 0x10cde6ae0, file "<ipython-input-41-f9a53483f10a>", line 2>)   6 LOAD_ConST    2 ('func_ge.<locals>.<genexpr>')   9 MAKE_FUNCTION 0  12 LOAD_GLOBAL   1 (y)  15 GET_ITER  16 CALL_FUNCTION 1 (1 positional, 0 keyword pair)  19 CALL_FUNCTION 1 (1 positional, 0 keyword pair)  22 POP_TOP  23 LOAD_ConST    0 (None)  26 RETURN_VALUE>>> ge_object = list(dis.get_instructions(func_ge))[1].argval>>> ge_object<pre object <genexpr> at 0x10cde6ae0, file "<ipython-input-41-f9a53483f10a>", line 2>>>> dis.dis(ge_object)  20 LOAD_FAST     0 (.0)        >>    3 FOR_ITER     15 (to 21)   6 STORE_FAST    1 (x)   9 LOAD_FAST     1 (x)  12 LOAD_ConST    0 (2)  15 BINARY_POWER  16 YIELD_VALUE  17 POP_TOP  18 JUMP_ABSOLUTE 3        >>   21 LOAD_ConST    1 (None)  24 RETURN_VALUE>>>

时序比较:

>>> %timeit [x**2 for x in range(10**6)]1 loops, best of 3: 453 ms per loop>>> %timeit list(x**2 for x in range(10**6))1 loops, best of 3: 478 ms per loop>>> %%timeitout = []for x in range(10**6):    out.append(x**2)...1 loops, best of 3: 510 ms per loop

由于属性查找缓慢,因此正常循环会稍慢。缓存它,然后再次计时。

>>> %%timeitout = [];append=out.appendfor x in range(10**6):    append(x**2)...1 loops, best of 3: 467 ms per loop

除了列表理解不再泄漏变量的事实之外,另一个区别是类似的东西不再有效:

>>> [x**2 for x in 1, 2, 3] # Python 2[1, 4, 9]>>> [x**2 for x in 1, 2, 3] # Python 3  File "<ipython-input-69-bea9540dd1d6>", line 1    [x**2 for x in 1, 2, 3]         ^SyntaxError: invalid syntax>>> [x**2 for x in (1, 2, 3)] # Add parenthesis[1, 4, 9]>>> for x in 1, 2, 3: # Python 3: For normal loops it still works    print(x**2)...149


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/645055.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号