假设我们有一个输入:
tuple_ = tuple(range(1000))
k = 400
让我们分析两个表达式:(tuple_[:k], tuple_[k+1:])
和(*tuple_[:k], *tuple_[k+1:])
,使用dis
模块来发现和比较执行了哪些重要操作under the hood.
100:
import dis
...
dis.dis("(tuple_[:k], tuple_[k+1:])")
1 0 LOAD_NAME 0 (tuple_)
2 LOAD_CONST 0 (None)
4 LOAD_NAME 1 (k)
6 BUILD_SLICE 2
8 BINARY_SUBSCR
10 LOAD_NAME 0 (tuple_)
12 LOAD_NAME 1 (k)
14 LOAD_CONST 1 (1)
16 BINARY_ADD
18 LOAD_CONST 0 (None)
20 BUILD_SLICE 2
22 BINARY_SUBSCR
24 BUILD_TUPLE 2
26 RETURN_VALUE
这里的重要运算是BUILD_SLICE
1、BUILD_SLICE
2和BUILD_TUPLE
,它们将表达式的运行时间合计为103 + 104 + 105(因为最终的元组BUILD_TUPLE
仅包含2个片/元组).
100:
dis.dis("(*tuple_[:k], *tuple_[k+1:])")
个
1 0 BUILD_LIST 0
2 LOAD_NAME 0 (tuple_)
4 LOAD_CONST 0 (None)
6 LOAD_NAME 1 (k)
8 BUILD_SLICE 2
10 BINARY_SUBSCR
12 LIST_EXTEND 1
14 LOAD_NAME 0 (tuple_)
16 LOAD_NAME 1 (k)
18 LOAD_CONST 1 (1)
20 BINARY_ADD
22 LOAD_CONST 0 (None)
24 BUILD_SLICE 2
26 BINARY_SUBSCR
28 LIST_EXTEND 1
30 LIST_TO_TUPLE
32 RETURN_VALUE
在这里,Python从BUILD_LIST
开始构建了一个空列表.这有几个原因:1)解包需要flattening个序列;2)并不是所有参数都需要解包,因此可以在最终容器上的不同点上安排展平.知道tuple
是不可变的,list
被用作内部存储.
这里的重要运算是BUILD_SLICE
1、LIST_EXTEND
1、BUILD_SLICE
2、LIST_EXTEND
2和LIST_TO_TUPLE
.它们将表达式的运行时间合计为105 + 106 + 107
这种复杂性似乎相当具有代表性.