前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记录一个python里面很神奇的操作,对一个包含列表的元组进行增量赋值

记录一个python里面很神奇的操作,对一个包含列表的元组进行增量赋值

原创
作者头像
用户1682544
发布2018-07-22 17:14:04
1.4K0
发布2018-07-22 17:14:04
举报

# 记录一个python里面很神奇的操作 #

今天记录一个很神奇的操作。关于序列的增量赋值。如果你很熟悉增量赋值,你也不妨看下去,我想说的是有关于增量赋值和元组之间一种神奇的操作。来自 **《流畅的Python》** 一书,让我们更加深入地了解里面的原理

## 神奇的操作 ##

```

>>>t = (1,2,[30,40])

>>>t[2] += [50,60]

```

**上面这段代码会出现什么样的情况**

a. t会变成(1,2,[30,40,50,60])

b. 因为tuple不支持对它的元素赋值,所以会抛出TypeError异常

c. 以上两个都不是

d. a和b都是对的

大多数人都会认为b是正确的,本书的作者也是这么认为的,但是实际上呢?却是选 **b**

**不要疑惑,就是这样,既报错,又成功进行了修改**

## 首先讲一下增量赋值 ##

我们使用增量赋值运算符 **+=** 和 **\*=** 等增量赋值运算符的时候(用 **+=** 举例),使用的是背后的特殊方法 **\_\_iadd\_\_**,如果没有实现这个方法则会退而求其次,使用 **\_\_add\_\_** .

**两者的区别是什么?**

用列表举例 **a+=b**,使用 **\_\_add\_\_** 的话就像是使用了`a.extend(b)`,如果使用 **\_\_add\_\_** 的话,则是 `a = a+b`,前者是直接在原列表上进行扩展,而后者是先从原列表中取出值,在一个新的列表中进行扩展,然后再将新的列表对象返回给变量,显然后者的消耗要大些。

## 继续将那个神奇的操作 ##

既然我们了解了变量赋值,那么我们就可以更深入一些了。

**t[2] += [50,60]** 实现原理:

1. 将t[2]的值,存入TOS(Top Of Stack 栈的顶端)。

2. 计算TOS +=b 。这一步可以完成,是因为TOS指向的是一个列表(可变对象)。

3. t[2] = TOS 赋值。这一步失败,并且报错,因为t是不可变的元组

**我们可以通过python tutor这个网站去找到里面运行的详细过程**

![image](C:/Users/19410/Pictures/python-%E5%A2%9E%E9%87%8F%E8%B5%8B%E5%80%BC.png)

![image](C:/Users/19410/Pictures/python-%E5%A2%9E%E9%87%8F%E8%B5%8B%E5%80%BC2.png)

欢迎关注我的公众号获取更多学习教程(Python雁横)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档