有一件事我一直想知道。在这个列表理解中拆分是执行一次还是多次?
l = [line.split()[i] for i in indexes]
我目前以这种方式进行列表理解:
l = line.rstrip().split()
l = [l for i in indexes]
但我不确定,是否有必要。除了是/否的答案之外,我绝对想知道,我如何通过进行 CPU 分析或阅读一些文档来自己发现这个问题。谢谢。
最佳答案
列表理解中左侧的表达式针对每个元素重新求值,是的。
如果你只需要评估一次,你需要完全按照你所做的去做;首先调用它并存储结果以在列表推导中重复使用。
来自List displays documentation :
In this case, the elements of the new list are those that would be produced by considering each of the
for
orif
clauses a block, nesting from left to right, and evaluating the expression to produce a list element each time the innermost block is reached.
强调我的。
您还可以使用 dis.dis()
function 反汇编列表推导式:
>>> 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
FOR_ITER
操作码开始循环(JUMP_ABSOLUTE
关闭循环),每次 LOAD_NAME 行
,LOAD_ATTR 拆分
和 CALL_FUNCTION
被执行。换句话说,字节码 13 到 19 实现了 line.split()
部分,并且每次都执行从字节码 7 到 29 的循环。
(Python 3 注意:列表理解有自己的作用域,您需要从外部代码对象常量中提取代码对象;dis.dis(compile('[line.split()[i] for i in indexes]', '', 'eval').co_consts[0])
).
关于Python:拆分函数是否在列表理解中被多次评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32297231/