Luk*_*are 55 python operator-overloading python-3.x
一个代码块有效,但另一个代码没有.哪个是有意义的,除了第二个块与第一个块相同,只是用速记写的操作.它们实际上是相同的操作.
l = ['table']
i = []
Run Code Online (Sandbox Code Playgroud)
for n in l:
i += n
print(i)
Run Code Online (Sandbox Code Playgroud)
输出: ['t', 'a', 'b', 'l', 'e']
for n in l:
i = i + n
print(i)
Run Code Online (Sandbox Code Playgroud)
输出:
TypeError:只能将列表(不是"str")连接到列表
是什么导致了这个奇怪的错误?
tim*_*geb 79
它们不必相同.
使用+操作员__add__在使用+=操作员调用时调用该方法__iadd__.完全取决于所讨论的对象,当调用其中一个方法时会发生什么.
如果您使用x += y但未x提供__iadd__方法(或方法返回NotImplemented),则将__add__其用作后备,意味着x = x + y会发生这种情况.
在列表的情况下,使用l += iterable实际扩展列表l的元素iterable.在您的情况下,extend操作期间会附加字符串中的每个字符(可迭代).
演示1:使用 __iadd__
>>> l = []
>>> l += 'table'
>>> l
['t', 'a', 'b', 'l', 'e']
Run Code Online (Sandbox Code Playgroud)
演示2:使用extend也是如此
>>> l = []
>>> l.extend('table')
>>> l
['t', 'a', 'b', 'l', 'e']
Run Code Online (Sandbox Code Playgroud)
演示3:添加列表和字符串引发a TypeError.
>>> l = []
>>> l = l + 'table'
[...]
TypeError: can only concatenate list (not "str") to list
Run Code Online (Sandbox Code Playgroud)
不使用+=会给你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 object
True
>>> l
[1, 2, 3]
>>> l_ref # mutations are seen across all names
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
但是,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 objects
False
>>> l
[1, 2, 3]
>>> l_ref
[]
Run Code Online (Sandbox Code Playgroud)
在某些情况下,这可能会产生细微的错误,因为它会+= 改变原始列表,同时
l = l + iterable构建一个新列表并重新分配名称l.
奖金