列表连接效率

3
假设我有两个列表,A = [1,2,3,4] 和 B = [4,5,6]
我想要一个包含 A 和 B 元素的新列表。(A 自身是否发生变化并不重要)
以下是我可以做的几件事情以及我的理解(如果我有误请告诉我):
A.extend(B) (B 中的元素将被添加到 A 中;A 本身将被更改)
C = A + B (创建一个全新对象 C,其中包含 A 和 B 的内容)
我想知道哪种方式更有效率,所以我想知道下面的假设是否正确:
对于 A.extend(B),我认为 Python 只需要进行三次列表添加操作(即 B 中的三个元素,每个元素都被添加到 A 中)。然而,在执行 A + B 时,Python 是否需要迭代访问 A 和 B 两个列表,从而进行七次列表添加操作呢?(即它必须创建一个新列表,遍历 A 并将所有元素放入其中,然后遍历 B 并将所有元素放入其中)。
我是否对解释器处理这些操作的方式或 Python 中这些操作的含义有所误解?

1
是的,A + B 总是需要复制 AB 的元素,而 A.extend(B) 仅在必要时才需要移动 A 中的元素以为 B 的元素腾出空间。有时这并不重要。 - Ry-
1个回答

2
以下是两种操作的字节码分析。两者之间没有很大的性能差异,唯一的区别是 .extend 的方式涉及一个 CALL_FUNCTION,在 Python 中比 BINARY_ADD 稍微昂贵一些。
但是,除非您正在处理大数据操作,否则这不应该成为问题。
>>> import dis
>>> a = [1,2,3,4]
>>> b = [4,5,6]
>>> def f1(a,b):
...  a.extend(b)
>>> def f2(a,b):
...  c = a+ b
>>> dis.dis(f1)
  2           0 LOAD_FAST                0 (a)
              3 LOAD_ATTR                0 (extend)
              6 LOAD_FAST                1 (b)
              9 CALL_FUNCTION            1
             12 POP_TOP             
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE        
>>> dis.dis(f2)
  2           0 LOAD_FAST                0 (a)
              3 LOAD_FAST                1 (b)
              6 BINARY_ADD          
              7 STORE_FAST               2 (c)
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接