连接两个列表 – “+ =”和extend()之间的区别
我已经看到实际上有两种(也许更多)的方式来连接Python中的列表:一种方法是使用extend()方法:
a = [1, 2] b = [2, 3] b.extend(a)
另一个使用加号(+)运算符:
b += a
现在我想知道:这两个选项中的哪一个是pythonic的列表连接的方式,两者是有区别的(我查了官方的Python教程,但是找不到关于这个主题的任何东西)。
字节码级别的唯一区别是.extend
方式涉及函数调用,在Python中比INPLACE_ADD
稍微贵INPLACE_ADD
。
除非你正在执行这个操作数十亿次,否则这是你应该担心的。 但是,这个瓶颈很可能会在其他地方出现。
你不能使用+ =作为非局部variables(variables不是局部的函数,也不是全局variables)
def main(): l = [1, 2, 3] def foo(): l.extend([4]) def boo(): l += [5] foo() print l boo() # this will fail main()
这是因为,对于扩展的情况,编译器会使用LOAD_DEREF
指令加载variablesl
,但是对于+ =它将使用LOAD_FAST
– 而您将得到*UnboundLocalError: local variable 'l' referenced before assignment*
你可以链接函数调用,但是你不能直接调用函数:
class A: def __init__(self): self.listFoo = [1, 2] self.listBar = [3, 4] def get_list(self, which): if which == "Foo": return self.listFoo return self.listBar a = A() other_list = [5, 6] a.get_list("Foo").extend(other_list) a.get_list("Foo") += other_list #SyntaxError: can't assign to function call
根据Python的禅宗 :
简单胜于复杂。
b += a
比b.extend(a)
更简单。
这些内置程序如此高度优化以至于没有真正的性能差异。
我会说,有一些差异,当它与numpy(我刚才看到问题连接两个列表问题,而不是numpy数组,但因为这可能是一个问题,像我这样的初学者,我希望这可以帮助某人谁寻求解决这个职位),例如。
import numpy as np a = np.zeros((4,4,4)) b = [] b += a
它将返回错误
ValueError:操作数不能与形状(0,)(4,4,4)
b.extend(a)
完美的作品
从python 3.5.2源代码:没有太大的区别。
static PyObject * list_inplace_concat(PyListObject *self, PyObject *other) { PyObject *result; result = listextend(self, other); if (result == NULL) return result; Py_DECREF(result); Py_INCREF(self); return (PyObject *)self; }