附加到元组中定义的列表-这是一个错误吗? [英] Append to a list defined in a tuple - is it a bug?

查看:114
本文介绍了附加到元组中定义的列表-这是一个错误吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有这段代码:

tup = ([1,2,3],[7,8,9])
tup[0] += (4,5,6)

会产生此错误:

TypeError: 'tuple' object does not support item assignment

这段代码:

tup = ([1,2,3],[7,8,9])
try:
    tup[0] += (4,5,6)
except TypeError:
    print tup

打印此:

([1, 2, 3, 4, 5, 6], [7, 8, 9])

这是预期的行为吗?

我意识到这不是一个很常见的用例.但是,虽然预期会出现错误,但我没想到列表会发生变化.

I realize this is not a very common use case. However, while the error is expected, I did not expect the list change.

推荐答案

是的.

元组不能更改.元组(如列表)是指向其他对象的结构.它不在乎那些对象是什么.它们可以是字符串,数字,元组,列表或其他对象.

A tuple cannot be changed. A tuple, like a list, is a structure that points to other objects. It doesn't care about what those objects are. They could be strings, numbers, tuples, lists, or other objects.

因此,对元组中包含的对象之一进行任何操作(包括在该对象是列表时追加到该对象)都与元组的语义无关.

So doing anything to one of the objects contained in the tuple, including appending to that object if it's a list, isn't relevant to the semantics of the tuple.

(想象一下,如果您编写了一个类,该类上具有导致其内部状态发生变化的方法.您不会期望不可能根据对象的存储位置在对象上调用这些方法).

(Imagine if you wrote a class that had methods on it that cause its internal state to change. You wouldn't expect it to be impossible to call those methods on an object based on where it's stored).

或另一个示例:

>>> l1 = [1, 2, 3]
>>> l2 = [4, 5, 6]
>>> t = (l1, l2)
>>> l3 = [l1, l2]
>>> l3[1].append(7)

一个列表和一个元组引用的两个可变列表.我是否应该能够做最后一行(答案:是).如果您认为答案是否定的,为什么不呢? t是否应更改l3的语义(答案:否).

Two mutable lists referenced by a list and by a tuple. Should I be able to do the last line (answer: yes). If you think the answer's no, why not? Should t change the semantics of l3 (answer: no).

如果您想要一个不可变的顺序结构对象,那么它应该一直是元组.

If you want an immutable object of sequential structures, it should be tuples all the way down.

此示例使用中缀运算符:

This example uses the infix operator:

许多操作都有就地"版本.以下功能 提供比平常更多的原始操作员访问权限 语法确实;例如,语句x + = y等效于x = operator.iadd(x,y).另一种表达方式是说z = operator.iadd(x,y)等效于复合语句z = x; ž + = y.

Many operations have an "in-place" version. The following functions provide a more primitive access to in-place operators than the usual syntax does; for example, the statement x += y is equivalent to x = operator.iadd(x, y). Another way to put it is to say that z = operator.iadd(x, y) is equivalent to the compound statement z = x; z += y.

https://docs.python.org/2/library/operator.html

所以这个:

l = [1, 2, 3]
tup = (l,)
tup[0] += (4,5,6)

等效于此:

l = [1, 2, 3]
tup = (l,)
x = tup[0]
x = x.__iadd__([4, 5, 6]) # like extend, but returns x instead of None
tup[0] = x

__iadd__行成功,并修改了第一个列表.因此,列表已更改. __iadd__调用返回突变列表.

The __iadd__ line succeeds, and modifies the first list. So the list has been changed. The __iadd__ call returns the mutated list.

第二行尝试将列表分配回元组,但失败.

The second line tries to assign the list back to the tuple, and this fails.

因此,在程序结尾处,列表已扩展,但+=操作的第二部分失败.有关详细信息,请参见此问题.

So, at the end of the program, the list has been extended but the second part of the += operation failed. For the specifics, see this question.

这篇关于附加到元组中定义的列表-这是一个错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆