为什么这两个操作(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是相同的。为什么与+操作不同?
- 完全尊重一个可行的新问题:我回滚到原始问题以保持它的干净(每个线程1个问题,请参阅so faq)。请在每个答案下面的评论主题中提出新的问题或后续问题。注意:您的编辑不会丢失,请单击历史记录,然后可以将其复制/粘贴到新问题中。
- 与+=类似:stackoverflow.com/questions/725782/…
- 似乎它给出了不同的答案,但不是那样。如果要使用+运算符添加值,则不能使用[]符号。C+=[C]将给出与append相同的结果。
解释"为什么":
+操作将数组元素添加到原始数组中。array.append操作将数组(或任何对象)插入到原始数组的末尾,这将导致在该位置引用self(因此是无限递归)。
这里的区别在于,当您通过连接元素来添加一个数组(它和其他数组一样被重载,请参阅本章关于序列的内容)时,+操作的作用是特定的。但是,append方法确实按照您的要求执行:将对象附加到您提供的右侧(数组或任何其他对象),而不是获取其元素。
另一种选择
如果您想使用一个类似于+运算符的函数(这里也显示了其他函数),请使用extend()。做相反的事情是不明智的:尝试用+操作符来模拟追加列表(参见前面的链接了解为什么)。
小历史
有趣的是,有点历史:1993年2月,Python中数组模块的诞生。这可能会让您感到惊讶,但数组是在序列和列表出现之后添加的。
- +因为我总是赞成准确的信息。官方文件链接始终是一个优势!
- "为什么"的另一部分:理智的人希望+是对称的:将列表与列表连接起来。
- +1、好点贝尼(虽然我可以把它看作是"理智的",说"右侧的对象被附加到左侧的数组中",但我个人认为当前的行为更为明智)。
- 这是一个组织良好的答案。
append将元素附加到列表中。如果您想用新列表扩展该列表,则需要使用extend。
1 2 3 4
| >>> c = [1, 2, 3]
>>> c.extend(c)
>>> c
[1, 2, 3, 1, 2, 3] |
- 我觉得很清楚为什么结果不同,因为操作不一样!如果出现+和extend产生不同的结果,我们会有一些想法。
- +1:为什么我不喜欢"为什么"的问题:append和+是不同的。这就是为什么。我喜欢这个答案,因为提供了更合理的做法。
- 这个网站不是关于回答问题的吗?人们问为什么PHP被称为PHP,为什么__lt__不能在Python中过载(现在它可以)。为什么问题是最基本的,但往往是最难回答的:它们要求的是本质,而不是指向手册的指针。当然,如果你不喜欢一个问题(我最不喜欢),那就不要回答;-)
- 为了进一步演示,也可以显示c += 和c.append(c[:])。
- @亚伯:为什么是埃多克斯1〔8〕?他们是不同的行动。这就是答案。"为什么"不如其他问题有用,比如"如何正确附加?"或者"这个导致无限递归的附加有什么问题?""我对X做了什么"或"我做X时出了什么问题"的形式的问题?或者"我应该做什么而不是X"也可以帮助人们学习,但是可以提供集中的、可用的、可操作的答案。
- 有趣的讨论,不确定我们是否应该…但是……:如果你问"我该怎么做X",你会回答obj.X或obj+X。更详尽的回答者也会解释为什么你应该选择其中一个,教提问者如何思考。是的,我同意,在大多数情况下,什么、如何等可以给出非常简单、非常明确的答案。为什么常被称为唯一答案无限的问题,但它教会我们思考。我们如何生活是无聊的(IMO),为什么我们生活更有趣。python首先提出了一个问题"为什么我们需要一种新的语言"。答案是语言。
串联运算符+是一个二进制中缀运算符,当应用于列表时,它返回一个新列表,其中包含两个操作数中每个操作数的所有元素。list.append()方法是list上的mutator方法,它将其单个object参数(在您的具体示例中,列表c附加到主题list上。在您的示例中,这会导致c附加对自身的引用(因此是无限递归)。
"+"串联的替代方法
list.extend()方法也是一种变异方法,它将其sequence参数与主题list参数连接起来。具体来说,它按照迭代顺序附加sequence的每个元素。
旁白
作为运算符,+将表达式的结果作为新值返回。作为一种非链接mutator方法,list.extend()在适当的位置修改了主题列表,没有返回任何内容。
数组
我之所以添加这个,是因为上面Abel的答案可能会混淆对列表、序列和数组的讨论。在序列和列表之后,将Arrays添加到python中,这是一种更有效的存储整型数据类型数组的方法。不要混淆Arrays和lists。它们不一样。
从数组文档:
数组是序列类型,其行为与列表非常相似,只是存储在其中的对象类型受到约束。类型是在对象创建时使用类型代码(单个字符)指定的。
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] |
号
其他信息:附加与扩展