Python在列表上附加()与+运算符,为什么这些会给出不同的结果?

Python append() vs. + operator on lists, why do these give different results?

为什么这两个操作(append()resp.+给出了不同的结果?

1
2
3
4
5
6
7
8
9
10
11
>>> 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是相同的。为什么与+操作不同?


解释"为什么":

+操作将数组元素添加到原始数组中。array.append操作将数组(或任何对象)插入到原始数组的末尾,这将导致在该位置引用self(因此是无限递归)。

这里的区别在于,当您通过连接元素来添加一个数组(它和其他数组一样被重载,请参阅本章关于序列的内容)时,+操作的作用是特定的。但是,append方法确实按照您的要求执行:将对象附加到您提供的右侧(数组或任何其他对象),而不是获取其元素。

另一种选择

如果您想使用一个类似于+运算符的函数(这里也显示了其他函数),请使用extend()。做相反的事情是不明智的:尝试用+操作符来模拟追加列表(参见前面的链接了解为什么)。

小历史

有趣的是,有点历史:1993年2月,Python中数组模块的诞生。这可能会让您感到惊讶,但数组是在序列和列表出现之后添加的。


append将元素附加到列表中。如果您想用新列表扩展该列表,则需要使用extend

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


串联运算符+是一个二进制中缀运算符,当应用于列表时,它返回一个新列表,其中包含两个操作数中每个操作数的所有元素。list.append()方法是list上的mutator方法,它将其单个object参数(在您的具体示例中,列表c附加到主题list上。在您的示例中,这会导致c附加对自身的引用(因此是无限递归)。

"+"串联的替代方法

list.extend()方法也是一种变异方法,它将其sequence参数与主题list参数连接起来。具体来说,它按照迭代顺序附加sequence的每个元素。

旁白

作为运算符,+将表达式的结果作为新值返回。作为一种非链接mutator方法,list.extend()在适当的位置修改了主题列表,没有返回任何内容。

数组

我之所以添加这个,是因为上面Abel的答案可能会混淆对列表、序列和数组的讨论。在序列和列表之后,将Arrays添加到python中,这是一种更有效的存储整型数据类型数组的方法。不要混淆Arrayslists。它们不一样。

从数组文档:

数组是序列类型,其行为与列表非常相似,只是存储在其中的对象类型受到约束。类型是在对象创建时使用类型代码(单个字符)指定的。


python列表是异构的,同一列表中的元素可以是任何类型的对象。表达式:c.append(c)将对象c附加到列表中。在这种情况下,它使列表本身成为列表的成员。

表达式c += c将两个列表相加,并将结果赋给变量c。重载的+运算符在列表上定义,以创建一个新列表,其内容是第一个列表中的元素和第二个列表中的元素。

所以,这些实际上是不同的表达式,用于通过设计来做不同的事情。


你要找的方法是extend()。从python文档中:

1
2
3
4
5
6
7
8
list.append(x)
    Add an item to the end of the list; equivalent to a[len(a):] = [x].

list.extend(L)
    Extend the list by appending all the items in the given list; equivalent to a[len(a):] = L.

list.insert(i, x)
    Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).


请参阅文档:

list.append(x)

  • Add an item to the end of the list; equivalent to a[len(a):] = [x].

list.extend(L)
- Extend the list by appending all the items in the given list;
equivalent to a[len(a):] = L.

c.append(c)将C作为元素附加到自身。由于列表是引用类型,因此会创建递归数据结构。

c += c相当于extend(c),它附加了c到c的元素。


您应该使用extend()。

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

其他信息:附加与扩展