我注意到在python中你可以附加到+=
的列表中执行此操作:
s = ['a', 'b', 'c']
s += 'd'
# s = ['a', 'b', 'c', 'd']
与执行s.append('d')
相同。但是没有s.remove('a')的等价物:
s -= 'a'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for -=: 'list' and 'str'
那么当您使用+=
时会发生什么?
答案 0 :(得分:5)
+=
上的 list
与执行s.append
相同。这跟s.extend
一样。在这种情况下,它恰好看起来相同,因为字符串是一个字符序列,所以一个字符的字符串是它自己的序列。一般来说,它是非常不同的。尝试使用数字或3个字符的字符串。
无论如何,“使用+=
时发生的事情”是这样的:
首先,语句a += b
查找方法a.__iadd__
。如果它存在(就像它可以在就地变异的对象上那样存在,比如list
),它就会被转换成这段代码:
a = a.__iadd__(b)
否则(与不可变对象一样,如int
),它被转换(松散地说)为:
a = a + b
list.__iadd__
存在。当然,在CPython中,它是用C实现的,但等效的Python代码非常简单:
def __iadd__(self, other):
self.extend(other)
return self
extend
方法与此相同:
def self.extend(self, iterable):
for element in iterable:
self.append(element)
所以,你的s += 'd'
有效地做到了这一点:
for char in 'd': # this loops once, with `char` being `'d'`
s.append(char)
s = s
显然,有很多东西都是优化的; extend
不必动态查找append
方法或在循环中调用它(可能多次扩展列表的存储),它必须具有与完成时相同的可见效果如此。
有关其工作原理的更多信息,请参阅文档的以下部分:
a += b
的解释方式。list
, tuple
, range
解释了list.__iadd__
,list.extend
和list.append
所做的事。collections.abc.MutableSequence
显示了一般预期支持的可变序列操作。+=
的细节(请注意,它不是Python中的运算符,与许多其他语言不同,而是一种只能出现在语句中的特殊事物,而不是表达式)。