There is something I've been wondering about for a while. Is the split executed once or multiple times in this list comprehension?
l = [line.split()[i] for i in indexes]
I currently do list comprehensions like these in this way:
l = line.rstrip().split()
l = [l for i in indexes]
But I'm not sure, whether it's necessary. In addition to a yes/no answer I would definitely like to know, how I could go about finding out about this myself by either by doing CPU profiling or reading some documentation. Thanks.
解决方案
The expression on the left in a list comprehension is evaluated anew for each element, yes.
If you only need it evaluated once, you need to do exactly what you did; call it first and store the result to be re-used in the list comprehension.
In this case, the elements of the new list are those that would be produced by considering each of the for or if clauses a block, nesting from left to right, and evaluating the expression to produce a list element each time the innermost block is reached.
Emphasis mine.
You could also disassemble the list comprehension using the 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
The FOR_ITER opcode starts the loop (with the JUMP_ABSOLUTE closing it), and each time a LOAD_NAME line, LOAD_ATTR split and CALL_FUNCTION are executed. In other words, the bytecodes 13 through to 19 implement the line.split() part, and it is executed each time through the loop, which runs from bytecodes 7 through to 29.
(Python 3 note: list comprehensions got their own scope and you'll need to extract the code object from the outer code object constants; dis.dis(compile('[line.split()[i] for i in indexes]', '', 'eval').co_consts[0])).