当前位置:  开发笔记 > 编程语言 > 正文

为什么list.append(x)比list + = l [x]更有效?

如何解决《为什么list.append(x)比list+=l[x]更有效?》经验,为你挑选了1个好方法。

附加到列表可能有两种方式:

1)

mat = []
for i in range(10):
    mat.append(i)

要么

2)

mat = []
for i in range(10):
    mat += [i]

从官方Python文档:

示例中显示的方法append()是为列表对象定义的; 它在列表的末尾添加了一个新元素.在此示例中,它等效于result = result + [a],但效率更高.

文档表明方法1更有效.为什么会这样?



1> PM 2Ring..:

即使使用.append需要方法调用,它实际上比使用增强赋值运算符更有效+=.

但是有一个更好的理由可以使用.append:当你要附加的列表不在本地范围内时,你可以这样做,因为它只是在外部作用域中调用对象的方法,而你不能在对象上执行赋值除非您将它们声明为全局(或非本地),否则这些不在本地范围内,这种做法通常最好避免.

这是一个例子:

mat = []

def test_append():
    for i in range(10):
        #mat += [i]
        mat.append(i)

def test_iadd():
    for i in range(10):
        mat += [i]

test_append()
print(mat)
test_iadd()
print(mat)

产量

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Traceback (most recent call last):
  File "./qtest.py", line 29, in 
    test_iadd()
  File "./qtest.py", line 25, in test_iadd
    mat += [i]
UnboundLocalError: local variable 'mat' referenced before assignment

当然,我们可以mat作为参数传递给函数:

mat = []

def test_append():
    for i in range(10):
        #mat += [i]
        mat.append(i)

def test_iadd2(mat):
    for i in range(10):
        mat += [i]

test_append()
print(mat)
test_iadd2(mat)
print(mat)

产量

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

一个test_iadd2较慢的原因是它必须[i]每个循环上构建一个新列表.

FWIW,这是字节码:

test_append
 21           0 SETUP_LOOP              33 (to 36)
              3 LOAD_GLOBAL              0 (range)
              6 LOAD_CONST               1 (10)
              9 CALL_FUNCTION            1
             12 GET_ITER            
        >>   13 FOR_ITER                19 (to 35)
             16 STORE_FAST               0 (i)

 23          19 LOAD_GLOBAL              1 (mat)
             22 LOAD_ATTR                2 (append)
             25 LOAD_FAST                0 (i)
             28 CALL_FUNCTION            1
             31 POP_TOP             
             32 JUMP_ABSOLUTE           13
        >>   35 POP_BLOCK           
        >>   36 LOAD_CONST               0 (None)
             39 RETURN_VALUE        

test_iadd2
 26           0 SETUP_LOOP              33 (to 36)
              3 LOAD_GLOBAL              0 (range)
              6 LOAD_CONST               1 (10)
              9 CALL_FUNCTION            1
             12 GET_ITER            
        >>   13 FOR_ITER                19 (to 35)
             16 STORE_FAST               1 (i)

 27          19 LOAD_FAST                0 (mat)
             22 LOAD_FAST                1 (i)
             25 BUILD_LIST               1
             28 INPLACE_ADD         
             29 STORE_FAST               0 (mat)
             32 JUMP_ABSOLUTE           13
        >>   35 POP_BLOCK           
        >>   36 LOAD_CONST               0 (None)
             39 RETURN_VALUE        

上面的字节码转储是使用dis模块生成的:

from dis import dis

mat = []

def test_append():
    for i in range(10):
        #mat += [i]
        mat.append(i)

def test_iadd2(mat):
    for i in range(10):
        mat += [i]

print('test_append')
dis(test_append)

print('\ntest_iadd2')
dis(test_iadd2)

推荐阅读
我我檬檬我我186
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有