2024-04-19 22:27:35 发布
网友
我有一个列表a,我想根据函数f更改元素{}。我能比天真的方式做得更好吗?在
a
f
for index in range(i, j): a[index] = f(a)
[我指的是更接近map(f, a)或更快的东西。]
map(f, a)
我不打算做计时练习,但我将向您展示各种选项变成什么样的内部代码。您的代码是naive。以切片为l值的基于映射的解决方案是map_lvalue_slice。以slice为l值的列表理解是list_comp_lvalue_slice。与列表理解相关的解决方案使用元组,称为tuple_lvalue_slice:
naive
map_lvalue_slice
list_comp_lvalue_slice
tuple_lvalue_slice
>>> from dis import dis >>> >>> def naive(a, f, i, j): ... for index, ai in enumerate(a[i:j], start=i): ... a[index] = f(ai) ... >>> def map_lvalue_slice(a, f, i, j): ... a[i:j] = map(f, a[i:j]) ... >>> def list_comp_lvalue_slice(a, f, i, j): ... a[i:j] = [f(ai) for ai in a[i:j]] ... >>> def tuple_lvalue_slice(a, f, i, j): ... a[i:j] = tuple(f(ai) for ai in a[i:j]) ... >>> dis(naive) 2 0 SETUP_LOOP 55 (to 58) 3 LOAD_GLOBAL 0 (enumerate) 6 LOAD_FAST 0 (a) 9 LOAD_FAST 2 (i) 12 LOAD_FAST 3 (j) 15 SLICE+3 16 LOAD_CONST 1 ('start') 19 LOAD_FAST 2 (i) 22 CALL_FUNCTION 257 25 GET_ITER >> 26 FOR_ITER 28 (to 57) 29 UNPACK_SEQUENCE 2 32 STORE_FAST 4 (index) 35 STORE_FAST 5 (ai) 3 38 LOAD_FAST 1 (f) 41 LOAD_FAST 5 (ai) 44 CALL_FUNCTION 1 47 LOAD_FAST 0 (a) 50 LOAD_FAST 4 (index) 53 STORE_SUBSCR 54 JUMP_ABSOLUTE 26 >> 57 POP_BLOCK >> 58 LOAD_CONST 0 (None) 61 RETURN_VALUE >>> >>> dis(map_lvalue_slice) 2 0 LOAD_GLOBAL 0 (map) 3 LOAD_FAST 1 (f) 6 LOAD_FAST 0 (a) 9 LOAD_FAST 2 (i) 12 LOAD_FAST 3 (j) 15 SLICE+3 16 CALL_FUNCTION 2 19 LOAD_FAST 0 (a) 22 LOAD_FAST 2 (i) 25 LOAD_FAST 3 (j) 28 STORE_SLICE+3 29 LOAD_CONST 0 (None) 32 RETURN_VALUE >>> >>> dis(list_comp_lvalue_slice) 2 0 BUILD_LIST 0 3 LOAD_FAST 0 (a) 6 LOAD_FAST 2 (i) 9 LOAD_FAST 3 (j) 12 SLICE+3 13 GET_ITER >> 14 FOR_ITER 18 (to 35) 17 STORE_FAST 4 (ai) 20 LOAD_FAST 1 (f) 23 LOAD_FAST 4 (ai) 26 CALL_FUNCTION 1 29 LIST_APPEND 2 32 JUMP_ABSOLUTE 14 >> 35 LOAD_FAST 0 (a) 38 LOAD_FAST 2 (i) 41 LOAD_FAST 3 (j) 44 STORE_SLICE+3 45 LOAD_CONST 0 (None) 48 RETURN_VALUE >>> >>> dis(tuple_lvalue_slice) 2 0 LOAD_GLOBAL 0 (tuple) 3 LOAD_CLOSURE 0 (f) 6 BUILD_TUPLE 1 9 LOAD_CONST 1 (<code object <genexpr> at 0xb748dc38, file "<stdin>", line 2>) 12 MAKE_CLOSURE 0 15 LOAD_FAST 0 (a) 18 LOAD_FAST 2 (i) 21 LOAD_FAST 3 (j) 24 SLICE+3 25 GET_ITER 26 CALL_FUNCTION 1 29 CALL_FUNCTION 1 32 LOAD_FAST 0 (a) 35 LOAD_FAST 2 (i) 38 LOAD_FAST 3 (j) 41 STORE_SLICE+3 42 LOAD_CONST 0 (None) 45 RETURN_VALUE
在我看来,能够最快解析到C代码的解决方案,最好是在一个紧循环中,因为它们可能使用的是大多数优化的C代码,而不是主要解释的指令。我更喜欢将slice作为l值解决方案而不是您的代码,我可能倾向于使用map解决方案,尽管我主要是一个列表理解者。在
另外,这里有证据证明它们是等效代码:
可以为切片指定:
a[i:j] = map(f, a[i:j])
使用列表理解。。。在
a[i:j] = [f(ai) for ai in a[i:j]]
或者map的等价物。。。在
map
我不打算做计时练习,但我将向您展示各种选项变成什么样的内部代码。您的代码是
naive
。以切片为l值的基于映射的解决方案是map_lvalue_slice
。以slice为l值的列表理解是list_comp_lvalue_slice
。与列表理解相关的解决方案使用元组,称为tuple_lvalue_slice
:在我看来,能够最快解析到C代码的解决方案,最好是在一个紧循环中,因为它们可能使用的是大多数优化的C代码,而不是主要解释的指令。我更喜欢将slice作为l值解决方案而不是您的代码,我可能倾向于使用map解决方案,尽管我主要是一个列表理解者。在
另外,这里有证据证明它们是等效代码:
^{pr2}$可以为切片指定:
使用列表理解。。。在
或者
^{pr2}$map
的等价物。。。在相关问题 更多 >
编程相关推荐