我看到在Python中实际上有两种(可能更多)方法来连接列表:
一种方法是使用extend()方法:
a = [1, 2]
b = [2, 3]
b.extend(a)
另一个使用加号(+)运算符:
b += a
现在我想知道:这两个选项中哪一个是“python”的方式来做列表连接,两者之间有区别吗?(我已经查阅了官方的Python教程,但找不到任何关于这个主题的任何东西)。
我看到在Python中实际上有两种(可能更多)方法来连接列表:
一种方法是使用extend()方法:
a = [1, 2]
b = [2, 3]
b.extend(a)
另一个使用加号(+)运算符:
b += a
现在我想知道:这两个选项中哪一个是“python”的方式来做列表连接,两者之间有区别吗?(我已经查阅了官方的Python教程,但找不到任何关于这个主题的任何东西)。
当前回答
我查了官方的Python教程,但找不到任何关于这个主题的东西
这个信息恰好隐藏在编程FAQ中:
... 对于列表,__iadd__[即+=]等价于在列表上调用extend并返回列表。这就是为什么我们说对于列表,+=是list.extend的“简写”
你也可以在CPython源代码中看到这一点:https://github.com/python/cpython/blob/v3.8.2/Objects/listobject.c#L1000-L1011
其他回答
我想说,有一些不同,当它与numpy(我刚刚看到的问题是关于连接两个列表,而不是numpy数组,但由于它可能是初学者的问题,如我,我希望这可以帮助谁寻求这篇文章的解决方案),对于ex。
import numpy as np
a = np.zeros((4,4,4))
b = []
b += a
它将返回错误
ValueError:操作数不能与形状(0,)(4,4,4)一起广播
B.extend (a)工作完美
字节码级别上的唯一区别是.extend方式涉及到一个函数调用,在Python中这比INPLACE_ADD方法稍微昂贵一些。
这真的没什么好担心的,除非你做了几十亿次这个操作。然而,瓶颈很可能存在于其他地方。
对于非局部变量(对于函数来说不是局部变量,也不是全局变量)不能使用+=
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指令加载变量l,但对于+=它将使用LOAD_FAST -并且你得到*UnboundLocalError:局部变量'l'在赋值之前引用*
根据Python进行数据分析。
注意,通过加法连接列表是一个相对昂贵的操作,因为必须创建一个新的列表并复制对象。使用extend将元素附加到现有列表,特别是如果您正在构建一个大型列表,通常是更可取的。” 因此,
everything = []
for chunk in list_of_lists:
everything.extend(chunk)
比连接替代更快:
everything = []
for chunk in list_of_lists:
everything = everything + chunk
列表上的.extend()方法适用于任何可迭代对象*,+=适用于某些可迭代对象,但可能会变得古怪。
import numpy as np
l = [2, 3, 4]
t = (5, 6, 7)
l += t
l
[2, 3, 4, 5, 6, 7]
l = [2, 3, 4]
t = np.array((5, 6, 7))
l += t
l
array([ 7, 9, 11])
l = [2, 3, 4]
t = np.array((5, 6, 7))
l.extend(t)
l
[2, 3, 4, 5, 6, 7]
Python 3.6 *非常确定.extend()适用于任何可迭代对象,但如果我不正确,请评论
修改:"extend()"改为"列表上的.extend()方法" 注:David M. Helmuth的评论很清晰。