python - 获取 "' 元组'对象的列表的变异元组不支持项目分配“

标签 python list tuples 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],)

最佳答案

+=是就地加法运算符。它做了件事:

  • 它调用obj.__iadd__(rhs)给对象机会就地改变对象。
  • 它重新绑定(bind)对 obj.__iadd__(rhs) 的引用调用返回。

通过使用 +=在存储在元组中的列表上,第一步成功; t[0]列表已就地更改,但第二步,重新绑定(bind) t[0]t[0].__iadd__ 的返回值失败,因为元组是不可变的。

后一步需要在可变和不可变对象(immutable对象)上支持相同的运算符:

>>> reference = somestr = 'Hello'
>>> somestr += ' world!'
>>> somestr
'Hello world!'
>>> reference
'Hello'
>>> reference is somestr
False

这里添加了一个不可变字符串,somestr被反弹到一个对象,因为字符串是不可变的。

>>> reference = somelst = ['foo']
>>> somelst += ['bar']
>>> somelst
['foo', 'bar']
>>> reference
['foo', 'bar']
>>> reference is somestr
True

此处的列表已就地更改,somestr被反弹到同一个对象,因为list.__iadd__()可以就地更改列表对象。

来自augmented arithmetic special method hooks documentation :

These methods are called to implement the augmented arithmetic assignments (+=, -=, *=, /=, //=, %=, **=, <<=, >>=, &=, ^=, |=). These methods should attempt to do the operation in-place (modifying self) and return the result (which could be, but does not have to be, self).

这里的解决方法是调用 t[0].extend()相反:

>>> t = ([1,2],)
>>> t[0].extend([3, 4, 5])
>>> t[0]
[1, 2, 3, 4, 5]

关于python - 获取 "' 元组'对象的列表的变异元组不支持项目分配“,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21361281/

相关文章:

python - 如何在 Pytorch 中实现上限 JSD 损失?

Python 使用正则表达式对相似模式进行分组

python - 如何将字符串列表转换为 python 中的字典列表?

c++ - boost::tuple 的搜索 vector

python - 元组到 DataFrame 转换的列表

python - 如何定义读取字符串元组的函数

python - Tkinter Spinbox 范围验证

python - 为什么 Python Tkinter Canvas Scroll 不会?

python - 在for语句中的django模板中按索引访问列表?

python - 如何进行递归子文件夹搜索并返回列表中的文件?