在Python中使用+和+ =运算符进行串联

Per*_*ous 38 python list concatenation python-3.x

最近,我发现串联列表时出现不一致。

因此,如果我使用+运算符,它不会将list与不同类型的任何对象连接在一起。例如,

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

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

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]
Run Code Online (Sandbox Code Playgroud)

那么,这仅仅是语言的语义还是其他原因?

Ror*_*ton 41

基本思想是,++=运算符在Python中不一定是相同的操作,并且列表的确不同。该+操作由__add__魔术方法执行,而该+=操作由__iadd__(就地添加)魔术方法执行。这些魔术方法来自运算符左侧的类型。

就地添加列表不需要右侧的列表,而只是可迭代的。然后从迭代器中逐项取出项目,并将其附加到列表中。这类似于列表的extend方法。因此,+=操作员不会忽略右侧对象的类型,它只是扩展了可以使用的可能类型。

这种行为有些令人困惑-一定是因为您是我两天来的第二个人,我对此问题提出了类似(但不是重复)的问题。但是,此行为很方便-我们现在有一种简单的方法可以将列表与任何可迭代对象组合在一起。

有关更多信息,请参见为什么Python列表在不能+元组时让您+ =元组?


如@khelwood的评论所述,的结果类型a += b很明显:的类型a。因此,类型b可以灵活。的结果类型a + b不明显。Python是一种严格类型化的语言,讨厌这种歧义。在Python中的禅规定

显式胜于隐式。

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

尽管实用性胜过纯度。

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