更新元组中的列表

Bal*_*Sun 12 python

我只是在翻译中玩弄并碰到了一些我不理解的东西.当我创建一个列表作为元素之一的元组,然后尝试更新该列表时,会发生一些奇怪的事情.例如,当我运行这个时:

tup = (1,2,3,[4,5])
tup[3] += [6]
Run Code Online (Sandbox Code Playgroud)

我明白了:

TypeError: 'tuple' object does not support item assignment
Run Code Online (Sandbox Code Playgroud)

这正是我的预期.然而,当我再次引用元组时,我得到:

>>> tup
(1, 2, 3, [4, 5, 6])
Run Code Online (Sandbox Code Playgroud)

所以即使python引发异常,列表实际上也已更新.这是如何运作的?我无法想象我实际上想要做这样的事情,但我仍然想了解发生了什么.谢谢.

Kar*_*rin 28

这实际上是在Python文档中记录的.

编辑:这是一个总结,这是一个更完整的答案.

  1. 当我们使用时+=,Python会__iadd__在项目上调用magic方法,然后在后续项目分配中使用返回值.
  2. 对于列表,__iadd__相当于调用extend列表然后返回列表.
  3. 因此,当我们打电话时tup[3] += [6],它相当于:

    result = tup[3].__iadd__([6])
    tup[3] = result
    
    Run Code Online (Sandbox Code Playgroud)
  4. 从#2开始,我们可以确定这相当于:

    result = tup[3].extend([6])
    tup[3] = result
    
    Run Code Online (Sandbox Code Playgroud)
  5. 第一行成功调用extend列表,因为列表是可变的,所以它会更新.但是,后续分配失败,因为元组是不可变的,并抛出错误.

  • 我认为答案会从增加中受益,因为延伸不只是`tup [3] .__ iadd __([6])`; 它是`tup [3] = tup [3] .__ iadd __([6])`.`list .__ iadd__`返回它正在变异的同一个对象只是方便. (2认同)