美文网首页
Python中list的append, extend, +=,

Python中list的append, extend, +=,

作者: SnailTyan | 来源:发表于2020-06-17 17:36 被阅读0次

    文章作者:Tyan
    博客:noahsnail.com  |  CSDN  |  简书

    0. 测试环境

    Python 3.6.9,dis库是Python自带的一个库,可以用来分析字节码,而字节码是CPython解释器的实现细节。

    1. 引言

    在Python中,扩展list的方法有多种,appendextend+=+都是列表扩展的方式,但它们的使用又有些许不同,需要根据具体情况来选择,本文主要分析它们的差异。

    2. 对比与分析

    2.1 list的函数方法

    • list.append(x)

    append方法会将x作为list的一项添加到末尾。等价于a[len(a):] = [x]

    • list.extend(iterable)

    extend方法会将后面的可迭代对象的所有项添加到列表中。

    2.2 代码测试

    • Test Case 1
    # Code
    a = [1, 2, 3]
    b = [4, 5, 6]
    a += b
    print(a)
    
    a = [1, 2, 3]
    b = [4, 5, 6]
    a.append(b)
    print(a)
    
    a = [1, 2, 3]
    b = [4, 5, 6]
    a.extend(b)
    print(a)
    
    a = [1, 2, 3]
    b = [4, 5, 6]
    c = a + b
    print(a)
    print(c)
    
    
    a = ['ab', 'cd']
    b = 'ef'
    a += b
    print(a)
    
    a = ['ab', 'cd']
    b = 'ef'
    a.append(b)
    print(a)
    
    a = ['ab', 'cd']
    b = 'ef'
    a.extend(b)
    print(a)
    
    a = ['ab', 'cd']
    b = 'ef'
    c = a + b
    print(a)
    print(c)
    
    # Output
    [1, 2, 3, 4, 5, 6]
    [1, 2, 3, [4, 5, 6]]
    [1, 2, 3, 4, 5, 6]
    [1, 2, 3]
    [1, 2, 3, 4, 5, 6]
    ['ab', 'cd', 'e', 'f']
    ['ab', 'cd', 'ef']
    ['ab', 'cd', 'e', 'f']
    Traceback (most recent call last):
      File "list_test.py", line 40, in <module>
        c = a + b
    TypeError: can only concatenate list (not "str") to list
    

    从输出结果来看,extend+=是等价的,会扩展原有的列表,+只能用来连接列表,且不改变原有的列表,会返回一个新列表,append会往原有列表中添加一个新的元素。

    • Test Case 2
    # Code
    import dis
    
    a = ['ab', 'cd']
    b = 'ef'
    print('Test +')
    dis.dis(lambda : a + b)
    a = ['ab', 'cd']
    b = 'ef'
    print('Test extend')
    dis.dis(lambda : a.extend(b))
    a = ['ab', 'cd']
    b = 'ef'
    print('Test append')
    dis.dis(lambda : a.append(b))
    
    
    a = ['ab', 'cd']
    b = 'ef'
    print('Test +=')
    #dis.dis(lambda : a += b)
    
    print('Test extend')
    dis.dis(compile("s = []; s.extend('abc')", '', 'exec'))
    print('Test +=')
    dis.dis(compile("s = []; s += 'abc'", '', 'exec'))
    
    
    # Ouput
    Test +
      6           0 LOAD_GLOBAL              0 (a)
                  2 LOAD_GLOBAL              1 (b)
                  4 BINARY_ADD
                  6 RETURN_VALUE
    Test extend
     10           0 LOAD_GLOBAL              0 (a)
                  2 LOAD_ATTR                1 (extend)
                  4 LOAD_GLOBAL              2 (b)
                  6 CALL_FUNCTION            1
                  8 RETURN_VALUE
    Test append
     14           0 LOAD_GLOBAL              0 (a)
                  2 LOAD_ATTR                1 (append)
                  4 LOAD_GLOBAL              2 (b)
                  6 CALL_FUNCTION            1
                  8 RETURN_VALUE
    Test +=
    Test extend
      1           0 BUILD_LIST               0
                  2 STORE_NAME               0 (s)
                  4 LOAD_NAME                0 (s)
                  6 LOAD_ATTR                1 (extend)
                  8 LOAD_CONST               0 ('abc')
                 10 CALL_FUNCTION            1
                 12 POP_TOP
                 14 LOAD_CONST               1 (None)
                 16 RETURN_VALUE
    Test +=
      1           0 BUILD_LIST               0
                  2 STORE_NAME               0 (s)
                  4 LOAD_NAME                0 (s)
                  6 LOAD_CONST               0 ('abc')
                  8 INPLACE_ADD
                 10 STORE_NAME               0 (s)
                 12 LOAD_CONST               1 (None)
                 14 RETURN_VALUE
    
    # Errors
      File "dis_test.py", line 20
        dis.dis(lambda : a += b)
                            ^
    SyntaxError: invalid syntax
    

    从输出结果来看,++=操作不会进行函数调用,而extendappend执行过程中会进行函数调用,当不注释dis.dis(lambda : a += b)时,执行会报错,虽然extend效果与+=是等价的,但+=在函数中不能使用非局部变量,而extend方法可以。

    • Test case 3
    # Code
    class Test():
        def __init__(self):
            self.a = [1, 2, 3]
    
        def get(self):
            return self.a
    
    b = [4, 5, 6]
    temp = Test()
    print('Before extend')
    print(temp.a)
    temp.get().extend(b)
    print('After extend')
    print(temp.a)
    
    print('+= ok')
    print('Before +=')
    print(temp.a)
    temp.a += b
    print('After +=')
    print(temp.a)
    
    print('+= error')
    #temp.get() += b
    
    # Ouput
    Before extend
    [1, 2, 3]
    After extend
    [1, 2, 3, 4, 5, 6]
    += ok
    Before +=
    [1, 2, 3, 4, 5, 6]
    After +=
    [1, 2, 3, 4, 5, 6, 4, 5, 6]
    += error
    
    # Error
        temp.get() += b
        ^
    SyntaxError: can't assign to function call
    

    上面这个例子是对+=extend使用范围的对比。

    3. 总结

    • extend效果与+=是等价的,主要差异在于字节码执行的方式不同,extend方法涉及了函数调用,开销更大一些。extend+=应用范围更广,某些情况下只能使用extend
    • +=会将后面的数据添加到原有的列表中,而+会返回一个新的列表,不改变原有列表。+只能连接列表。
    • append方式会将参数作为列表的一项添加到原有的列表中。

    References

    1. https://stackoverflow.com/questions/725782/in-python-what-is-the-difference-between-append-and/725882

    2. https://stackoverflow.com/questions/252703/what-is-the-difference-between-pythons-list-methods-append-and-extend

    3. https://docs.python.org/3.6/tutorial/datastructures.html

    4. https://stackoverflow.com/questions/3653298/concatenating-two-lists-difference-between-and-extend

    5. https://stackoverflow.com/questions/39689099/can-someone-explain-this-expression-alena-x-equivalent-to-list-append

    相关文章

      网友评论

          本文标题:Python中list的append, extend, +=,

          本文链接:https://www.haomeiwen.com/subject/zefsxktx.html