zha*_*hen 3 python tuples list immutability
我正在尝试修改元组中的列表,该append方法有效,而+=运算符工作但引发异常,说无法修改元组.我知道一个元组是不可变的,但我不是想改变它.为什么会这样?
In [36]: t=([1,2],)
In [37]: t[0].append(123)
In [38]: t
Out[38]: ([1, 2, 123],)
In [39]: t[0]+=[4,5,]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-39-b5b3001fbe03> in <module>()
----> 1 t[0]+=[4,5,]
TypeError: 'tuple' object does not support item assignment
In [40]: t
Out[40]: ([1, 2, 123, 4, 5],)
Run Code Online (Sandbox Code Playgroud)
+=是就地添加运算符.它做了两件事:
obj.__iadd__(rhs)给对象提供就地变异对象的机会.obj.__iadd__(rhs)调用返回的内容.通过使用+=存储在元组中的列表,第一步成功; 该t[0]列表被改变原地的,但第二个步骤,重新绑定t[0]到的返回值t[0].__iadd__,因为一个元组是不可改变的失败.
需要后一步来支持可变和不可变对象上的相同运算符:
>>> reference = somestr = 'Hello'
>>> somestr += ' world!'
>>> somestr
'Hello world!'
>>> reference
'Hello'
>>> reference is somestr
False
Run Code Online (Sandbox Code Playgroud)
这里添加了一个不可变的字符串,somestr并被反弹到一个新对象,因为字符串是不可变的.
>>> reference = somelst = ['foo']
>>> somelst += ['bar']
>>> somelst
['foo', 'bar']
>>> reference
['foo', 'bar']
>>> reference is somestr
True
Run Code Online (Sandbox Code Playgroud)
这里列表已就地更改somestr并被反弹到同一个对象,因为list.__iadd__()可以就地更改列表对象.
这些方法称为实现增强的算术作业(
+=,-=,*=,/=,//=,%=,**=,<<=,>>=,&=,^=,|=).这些方法应该尝试就地进行操作(修改self)并返回结果(可能是,但不一定是这样self).
这里的解决方法是t[0].extend()改为:
>>> t = ([1,2],)
>>> t[0].extend([3, 4, 5])
>>> t[0]
[1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)