Python中使用+和+=运算符进行连接

38

最近,我注意到在连接列表时存在不一致性。

如果使用+运算符,则无法将列表与任何不同类型的对象连接起来。例如,

l = [1,2,3]
l = l + (4,5)        #TypeError: can only concatenate list (not "tuple") to list

但是,如果我使用+=运算符,它会忽略对象的类型。例如:

l = [1,2,3]
l += "he"            #Here, l becomes [1, 2, 3,"h", "e"]

l += (56, 67)        #Here, l becomes [1, 2, 3,"h", "e", 56, 67]

那么,这只是语言的语义问题还是其他原因?


21
如果您在不同类型的操作数中使用 +,则会存在关于结果类型的歧义。而使用 +=,则意味着左操作数决定了结果的类型。 - khelwood
1
+= for lists is more or less equivalent to list.extend() - Tomerikoo
1个回答

41
基本思想是,在Python中,++=操作符不一定是相同的操作,对于列表它们确实是不同的。 +操作由__add__魔法方法执行,而+=操作由__iadd__(原地加)魔法方法执行。这些魔法方法来自操作符左侧的类型。
对于列表的原地添加并不需要右侧的列表,只需要一个可迭代对象。然后从可迭代对象中逐个获取项目并附加到列表中。这类似于列表的extend方法。因此,+=操作符并没有忽略右侧对象的类型,它只是扩展了可以使用的可能类型。
这种行为有点令人困惑--因为你是我在两天内看到的第二个提出类似问题(但不完全相同)的人。但是,这种行为很方便--我们现在有了一种将列表与任何可迭代对象结合的简单方法。
有关更多信息,请参见为什么Python列表允许您+=元组,而不能+元组?
正如@khelwood的评论所述,a += b 的结果类型很明显: a 的类型。因此,b 的类型可以是灵活的。 a + b 的结果类型并不明显。Python 是一种严格类型的语言,不喜欢这种歧义。Python 之禅指出:

明确胜于隐晦。

面对模棱两可,拒绝猜测的诱惑。

实用性胜过纯粹性。

因此,当前的行为非常符合 Python 之禅。我注意到在 Zen 中没有关于一致性的内容。


Java中有类似的东西。 - Eric Duminil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接