python用split拆分多次,Python:是否在列表理解中对split函数进行了多次评估?

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])).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值