有件事我一直想知道有一段时间了。在此列表理解中,分割是执行一次还是多次?
l = [line.split()[i] for i in indexes]
我目前以这种方式列出这样的理解:
l = line.rstrip().split()
l = [l for i in indexes]
但我不确定,是否有必要。除了是/否答案之外,我还想知道如何通过 CPU 分析或阅读一些文档来亲自了解这一点。谢谢。
对于每个元素,都会重新计算列表推导式左侧的表达式,是的。
如果您只需要评估一次,则需要完全按照您所做的操作;首先调用它并存储结果以便在列表理解中重复使用。
来自列表显示文档:
在这种情况下,新列表的元素是通过考虑每个元素而产生的元素for
or if
子句是一个块,从左到右嵌套,并在每次到达最里面的块时评估表达式以生成列表元素.
强调我的。
您还可以使用以下命令反汇编列表理解dis.dis()功能:
>>> import dis
>>> dis.dis(compile('[line.split()[i] for i in indexes]', '', 'eval'))
1 0 BUILD_LIST 0
3 LOAD_NAME 0 (indexes)
6 GET_ITER
>> 7 FOR_ITER 22 (to 32)
10 STORE_NAME 1 (i)
13 LOAD_NAME 2 (line)
16 LOAD_ATTR 3 (split)
19 CALL_FUNCTION 0
22 LOAD_NAME 1 (i)
25 BINARY_SUBSCR
26 LIST_APPEND 2
29 JUMP_ABSOLUTE 7
>> 32 RETURN_VALUE
The FOR_ITER
操作码开始循环(使用JUMP_ABSOLUTE
关闭它),并且每次LOAD_NAME line
, LOAD_ATTR split
and CALL_FUNCTION
被处决。换句话说,字节码 13 到 19 实现了line.split()
部分,每次循环都会执行它,该循环从字节码 7 到 29。
(Python 3 注意:列表推导式有自己的作用域,您需要从外部代码对象常量中提取代码对象;dis.dis(compile('[line.split()[i] for i in indexes]', '', 'eval').co_consts[0])
).
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)