i = i + n 真的和 i += n 一样吗?

一个代码块有效,但另一个无效。这是有意义的,除了第二个块与第一个块相同,只有一个用速记写的操作。它们实际上是相同的操作。


l = ['table']

i = []

版本 1

for n in l:

    i += n

print(i)

输出: ['t', 'a', 'b', 'l', 'e']


版本 2

for n in l:

    i = i + n

print(i)

输出:


类型错误:只能将列表(不是“str”)连接到列表


是什么导致了这个奇怪的错误?


尚方宝剑之说
浏览 269回答 2
2回答

波斯汪

它们不必相同。使用+运算符调用方法的__add__同时使用+=运算符调用__iadd__。调用这些方法之一时会发生什么完全取决于所讨论的对象。如果您使用x += y但x不提供__iadd__方法(或方法返回NotImplemented),__add__则用作回退,这意味着x = x + y会发生。在列表的情况下, usingl += iterable实际上l使用 的元素扩展列表iterable。在您的情况下,字符串中的每个字符(它是可迭代的)都在extend操作期间被附加。演示 1:使用 __iadd__>>> l = []>>> l += 'table'>>> l['t', 'a', 'b', 'l', 'e']演示 2:使用extend也一样>>> l = []>>> l.extend('table')>>> l['t', 'a', 'b', 'l', 'e']演示 3:添加一个列表和一个字符串会产生一个TypeError.>>> l = []>>> l = l + 'table'[...]TypeError: can only concatenate list (not "str") to list不使用+=为您提供了TypeError此处,因为仅__iadd__实现了扩展行为。演示 4:常见陷阱:+=不构建新列表。我们可以通过与is操作员检查相同的对象身份来确认这一点。>>> l = []>>> l_ref = l # another name for l, no data is copied here>>> l += [1, 2, 3] # uses __iadd__, mutates l in-place>>> l is l_ref # confirm that l and l_ref are names for the same objectTrue>>> l[1, 2, 3]>>> l_ref # mutations are seen across all names[1, 2, 3]但是,l = l + iterable语法确实构建了一个新列表。>>> l = []>>> l_ref = l # another name for l, no data is copied here>>> l = l + [1, 2, 3] # uses __add__, builds new list and reassigns name l>>> l is l_ref # confirm that l and l_ref are names for different objectsFalse>>> l[1, 2, 3]>>> l_ref[]在某些情况下,这会产生细微的错误,因为会+= 改变原始列表,同时l = l + iterable构建新列表并重新分配name l。

千巷猫影

如果在第二种情况下,您环绕一个列表n以避免错误:for n in l:    i = i + [n]print(i)你得到['table']所以它们是不同的操作。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python