假设一个元祖 t = ([1],[1,2],[1,2,3]) 执行这些操作: t[1].append(3) # 成功
t[1] += [3] # 报错 TypeError: 'tuple' object does not support item assignment,但是 t 的已经被修改成([1], [1, 2, 3], [1, 2, 3])
t[1] = t[1] + [3] # 报错,并且修改失败
这是为什么呢?
1
freetstar 2017-07-10 10:22:47 +08:00
假设一个元祖 t = ([1],[1,2],[1,2,3]) 执行这些操作:t[1].append(3) # 成功
t[1]此时是[1,2]这个列表,列表 append 操作 ok ------------------------------------------------------------------------------------- t[1] += [3] # 报错 TypeError: 'tuple' object does not support item assignment 元组不支持赋值操作,这个可以理解。为什么能改掉列表里的内容,是不是和+=操作符有关。 等大神来解答 |
2
dozer47528 2017-07-10 10:26:02 +08:00
首先,元组不能修改,这个报错很正常
但为什么修改成功了呢!? 看上去 python 对 array += array 的内部实现是用了 append, 而不是创建一个新的 array。 这个要验证也很简单,看一下源码就行了。 |
3
lln133208 2017-07-10 10:28:11 +08:00
流畅的 Python 中有讲这个问题
|
4
sunbeams001 2017-07-10 10:30:36 +08:00
有讨论过这个问题
/t/357570 |
5
blacklinux OP @lln133208 这个问题要如何解答?
|
6
billion 2017-07-10 10:31:22 +08:00
元组一旦创建就不能修改。任何尝试直接修改元组的行为都会报错。
但是,在 Python 中,列表是这种结构,你保存到元组中的是一个列表的 [引用] , [相当]于一个指针,它指向存放这个列表的实际位置。所以当你用 append 的时候,修改的是那个实际的列表,而这个“指针”不变。但是当你使用+号的时候,你相当于创建了一个新的列表,然后想把元组的下标为 1 的元素修改为新的“指针”,所以这个就是修改元组的行为。 |
7
dozer47528 2017-07-10 10:33:48 +08:00
看过源码了:
所以直接操作原数组的,并没有创建一个新的,所以出现了这种状况。 |
8
lln133208 2017-07-10 10:37:14 +08:00
@blacklinux 书中的意思和 6 楼差不多,最后还给出了几个建议。
|
9
blacklinux OP @billion 懂了:
t[1].append(3) #是直接对列表进行修改,没有赋值,不报错 t[1] += [3] # 先堆栈操作,然后在赋值,由于元祖不可更改,所以赋值会失败,但由于堆栈已经操作过了,所以列表的内容还是改变了 t[1] = t[1] + [3] # 直接赋值,会失败 |
10
ETiV 2017-07-10 11:14:23 +08:00 via iPhone
看标题愣了一下
元祖不是买蛋糕的吗…… |
11
qyc666 2017-07-10 11:49:17 +08:00 via iPhone
元祖……雪月饼?
|