Python 的 append() 和 + 运算符在列表中为什么结果不同?

149 投票
7 回答
177253 浏览
提问于 2025-04-15 17:45

这两个操作(append()+)为什么会得到不同的结果呢?

>>> c = [1, 2, 3]
>>> c
[1, 2, 3]
>>> c += c
>>> c
[1, 2, 3, 1, 2, 3]
>>> c = [1, 2, 3]
>>> c.append(c)
>>> c
[1, 2, 3, [...]]
>>> 

在最后一种情况下,实际上是出现了无限递归。c[-1]c是一样的。那为什么用+操作时就不一样呢?

7 个回答

22

append 是把一个元素添加到列表里。如果你想用一个新列表来扩展原来的列表,就需要使用 extend

>>> c = [1, 2, 3]
>>> c.extend(c)
>>> c
[1, 2, 3, 1, 2, 3]
33

连接运算符 + 是一个二元运算符,当它用于列表时,会返回一个新列表,这个新列表包含了两个操作数的所有元素。list.append() 方法是一个修改器,它会把你传入的单个对象(在你的例子中是列表 c)添加到目标列表中。在你的例子里,这就导致了 c 自己添加了一个引用(所以出现了无限递归)。

使用 '+' 连接的替代方法

list.extend() 方法也是一个修改器,它会把你传入的序列与目标列表连接起来。具体来说,它会按顺序将序列中的每个元素添加到目标列表中。

补充说明

作为一个运算符,+ 会返回一个新值。而作为一个非链式的 mutator 方法,list.extend() 会直接修改目标列表,并且不返回任何值。

数组

我加上这一部分是因为上面的 Abel 的回答可能会让人对列表、序列和数组混淆。 数组 是在 Python 中引入的,目的是为了更高效地存储整型数据类型的数组。不要把 arrayslists 混淆,它们是不同的。

来自 数组文档

数组是序列类型,行为与列表非常相似,但存储的对象类型是有限制的。这个类型是在创建对象时通过一个类型代码指定的,类型代码是一个单字符。

181

解释一下“为什么”:

在Python中,+操作是用来把一个数组的元素加到另一个数组里的。而array.append操作则是把一个数组(或者其他任何对象)放到原数组的最后面,这样在那个位置就会出现一个自我引用(这就是你在处理列表时出现无限递归的原因,不过在数组中,你会遇到类型错误)。

这里的区别在于,+操作在你加一个数组时是有特定功能的(它像其他操作一样被重载,具体可以看这一章关于序列的内容),它是把元素连接在一起。而append方法则是字面意思地执行你要求的操作:把你给它的右边的对象(数组或其他对象)放到当前数组的最后,而不是取它的元素。

一个替代方案

如果你想用一个和+操作类似的功能,可以使用extend()。这样做比用+操作来模拟append更明智(其他人也在这里提到过)。下面会详细讲讲列表:

列表

[编辑] 有几位评论者提到这个问题是关于列表而不是数组。问题的确发生了变化,不过我应该早一点提到这一点。

上面关于array的内容大部分也适用于列表:

  • +操作符是用来把两个列表连接在一起的。这个操作会返回一个新的列表对象。
  • List.append并不是把一个列表加到另一个列表上,而是把一个单独的对象(这里是一个list)放到你当前列表的最后。因此,把c加到自己上,就会导致无限递归。
  • 和数组一样,你可以使用List.extend来把一个列表扩展到另一个列表(或者其他可迭代对象)。这样会直接改变你当前的列表,而不是像+那样返回一个新列表。

一点历史

有趣的是,简单说说历史:Python中的数组模块诞生于1993年2月。可能会让你惊讶的是,数组是在序列和列表出现很久之后才被添加进来的。

撰写回答