“为什么”问题的问题在于通常它们可能有不止一个含义。我会尝试回答您可能想到的每个问题。
“为什么可能会有不同的工作方式?” 可以通过例如这个来解答。基本上,+=
尝试使用对象的不同方法: __iadd__
(仅在左边检查),对于 +
,则是 __add__
和 __radd__
(如果左侧没有 __add__
则在右侧检查“反向添加”)
“每个版本究竟做了什么?” 简单地说,list.__iadd__
方法和 list.extend
做的事情是相同的(但由于语言设计,仍然需要赋值回去)。
这也意味着例如
>>> a = [1,2,3]
>>> b = a
>>> a += [4] # uses the .extend logic, so it is still the same object
>>> b # therefore a and b are still the same list, and b has the `4` added
[1, 2, 3, 4]
>>> b = b + [5] # makes a new list and assigns back to b
>>> a # so now a is a separate list and does not have the `5`
[1, 2, 3, 4]
+
符号创建一个新对象,但需要明确另一个列表并将其添加到该对象中,而不是尝试从不同的序列中提取元素。
"为什么使用+=这种方式很有用?因为它更有效率; extend
方法不必创建一个新对象。当然,有时会产生一些令人惊讶的影响(如上所述),总体而言,Python并不完全关注效率,但这些决策是在很长时间以前做出的。
"为什么不允许使用+来添加列表和元组?"请参见此处(感谢@splash58); 其中之一的想法是(tuple + list)应该产生与(list + tuple)相同的类型,而结果应该是哪种类型并不清楚。+=
则没有这个问题,因为a+=b
显然不应该改变a
的类型。