在+
和+=
运算符重载上的列表和元组行为:
这失败了:
>>> [1,2] + (3,4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
但这可行:
>>> l = [1,2]
>>> l += (3,4)
>>> l
[1, 2, 3, 4]
设置和冻结设置的行为不同:
这有效:
>>> {1,2} | frozenset({3,4})
{1, 2, 3, 4}
这也有效:
>>> s = {1,2}
>>> s |= frozenset({3,4})
>>> s
{1, 2, 3, 4}
为什么[1,2] + (3,4)
与{1,2} | frozenset({3,4})
的工作方式不同?
为什么两者不同?是否有一个原因?是向后兼容的东西还是与内部相关的东西?
我对为什么的实现方式更感兴趣,而这种实现方式不是 what 技术上是在后台进行的。我怀疑Python语言是经过精心设计的,我想理解这种差异的原因。
答案 0 :(得分:0)
主要区别在于实现方式不一致且令人讨厌。
在此示例中:
x
人们会期望y
会转换为>>> l = [1,2]
>>> l += (3,4)
并失败,但是l += (3, 4)
/ l = l + (3, 4)
的实现是不同的,并且会更改原始对象 。但这实际上可以大致理解为:
list.__iadd__
通过校准set.__iadd__
,可以(可能)任何可迭代的方式调用它:
l.extend((3, 4))
这样做可能是出于效率方面的考虑,但是它是隐式的,并且很容易出错。这使它成为惯用的代码模式:
list.extend
更好地扩展 ,而无需用户考虑。
出于性能原因,对本机数据结构的自定义实现(>>> l = [1]
>>> l += {11, 31, 21} # <--- this should be a lot more troubling (no order)
>>> l
[1, 11, 21, 31] # worked, but obviously no order guarantees
,l = []
for items in items_generator:
l += items
)是例外。