Python List 方法中 append 与 extend 的区别
文章目录
最近在处理列表中的字符串添加的问题时,发现 Python 中 append 和 extend 两种方法的表现有点出乎我的意料,一番搜索后,找到了一篇十分精彩的回答,如下,我尝试将其翻译一下,以兹学习。
原答案地址为:What is the difference between the list methods append and extend? Plain address: https://stackoverflow.com/a/28119966
以下为原回答:
List 方法 append 和 extend 有哪些不同点?
append
将其参数视为单一元素地添加到列表之后。列表的长度自增一。extend
逐一地将其参数添加到列表之后,扩展了列表。列表的长度变化取决于可迭代的参数中有多少元素。
append
list.append
方法将对象附加到列表的末尾。
|
|
无论对象是数字,字符串,另一个列表,或者其他的对象,它都将作为一个单一元素添加到列表末尾。
|
|
所以请牢记在心,一个列表就是一个对象。如果你将一个列表添加到另一个列表中,前者将作为一个单一元素,添加到被添加列表的末尾(也许和你预期的不一样):
|
|
extend
list.extend
方法通过从可迭代对象中添加元素到列表中来扩展列表:
|
|
所以使用 extend 方法时,可迭代对象中的每一个元素都被添加到列表中。举个栗子:
|
|
请牢记在心,字符串同样也是可迭代对象,所以如果你用字符串来扩展列表,你将把字符串中的每一个字符都(单独地)添加到列表中了(也许和你预期的不一样):
|
|
操作符重载,__add__
(+) 和 __iadd__
(+=)
+
和 +=
操作符均定义在了 列表
中。它们在语义上类似于扩展。
my_list + another_list
在内存中创建了第三个列表对象,所以你可以将其结果返回,但它要求第二个迭代对象为列表。
my_list += another_list
原地修改了列表(它 是 原地操作符,并且列表是可变对象,正如我们所看到的那样)所以它不会创建一个新列表对象。它运行得如 extend 一样,所以第二个可迭代对象可以是任意可迭代对象。
不要混淆了 my_list = my_list + another_list
和 +=
操作 – 前者将一个新列表赋值到 my_list
。
时间复杂度
Append
为常数时间复杂度,O(1)。
Extend
为线性时间复杂度,O(k)。
多次重复地调用 append
会增加其复杂度,使得 append
的时间复杂度与 extend
相同,并且,由于 extend
是 C 实现的,当你需要重复地将可迭代对象添加到列表中时,使用 extend
方法总是更快的。
性能对比
既然 append
可以实现和 extend
的同等效果,你可能想知道谁的性能更好。下列函数的效果相同:
|
|
测试一下:
|
|
就时间测量问题多说一句
有评论说到:
==完美的答案,我还想知道仅仅添加一个元素时的性能对比==
充分遵循语义行事。如果你想将一个可迭代对象的所有元素都添加到列表中,使用 extend
方法。如果你只是想添加一个元素,使用 append
方法。
让我们设计一个实验看看:
|
|
我们会看到,不遗余力地使用 extend
去创建一个可迭代对象是在浪费时间:
|
|
我们学到的是,仅当我们需要添加一个元素时,使用 extend
方法并无更多的好处。
同样地,上述的具体时间测量值并不是关键,关键是,在 Python 中,正确地遵循语义就是在 做正确的事。
可以想见,你可能会测试两个类似操作的所需时长并获得模糊或相反的结果。但我们只要关注于做语义正确的事情就好了。
结论
我们可以看到 extend
方法语义上更为简洁,并且它比 append
方法运行得更快,当你打算将一个可迭代对象的每一个元素都添加到列表中时。
如果你只有一个单一的元素(而不是一个可迭代对象)需要添加到列表时,使用 append
方法。