Python:序列的增量赋值
增量赋值运算符有 += 和 *=。+= 背后的特殊方法是 __iadd__,如果一个类没有实现 __iadd__ 方法,Python 会退一步调用 __add__ 方法。这两个方法的区别在于,__iadd__ 为就地改动,不会改变原值的内存地址,而 __add__ 方法会得到一个新对象。
考虑下面一个表达式:
a += b
如果 a 实现了 __iadd__ 方法,a 会就地改动(内存地址不变)。如果 a 没有实现 __iadd__ 方法,那么 a += b 这个表达式的效果就变得跟 a = a + b 一样了,生成一个新的对象赋给 a。
总体来讲,可变序列一般都实现了 __iadd__ 方法,因此 += 是就地加法,而不可变序列根本就不支持这个操作。
*= 和 += 一样,只是背后的特殊方法为 __imul__。
a = [1, 2, 3]
b = [4, 5, 6]
print("id(a) = %d" % id(a))
a += b
print("id(a) = %d" % id(a)) c = [1, 2, 3]
print("id(c) = %d" % id(c))
c = c + b
print("id(c) = %d" % id(c)) d = (1, 2, 3)
print("id(d) = %d" % id(d))
d *= 2
print("id(d) = %d" % id(d))
运行结果如下:
id(a) = 1298277978824
id(a) = 1298277978824
id(c) = 1298277978696
id(c) = 1298277978632
id(d) = 1298277972872
id(d) = 1298277136616
了解了序列的增量赋值,我们来看 Leonardo Rochael 在 2013 年的 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,但其实答案是 D。在控制台运行代码,显示结果如下:

总结:
1、对不可变序列进行重复拼接操作的话,效率会很低,因为每次都要新建一个序列,然后把原来序列中的元素复制到新的序列里,然后再追加新的元素。
2、不要把可变对象放在元组里面。
3、增量赋值不是一个原子操作,我们刚才也看到了,它虽然抛出了异常,但 t 的值还是改变了。
Python:序列的增量赋值的更多相关文章
- 关于python中的增量赋值的理解
增量赋值运算符 += 和 *= 的表现取决于它们的第一个操作对象 += 操作首先会尝试调用对象的 __ iadd__方法,如果没有该方法,那么尝试调用__add__方法,所以+= 与 + 的区别实质是 ...
- python学习记录20190122_增量赋值
python中的增量赋值 一,在python中a=a+b和a+=b有区别吗 **1,对可变的数据类型 a=[1,2,3]print(id(a)) #1602469350792b=[4,5]a=a+bp ...
- 流畅的python python 序列
内置序列 容器类型 list .tuple和collections.deque这些序列能放入不同的类型的数据 扁平序列 str.byets.bytearray.memoryview(内存视图)和arr ...
- Python序列构成的数组
1.内置序列类型 容器序列:list,tuple,collections.deque (能存放不同类型) 扁平序列:str,bytes,bytearray,memoryview,array.array ...
- [Python笔记][第二章Python序列-tuple,dict,set]
2016/1/27学习内容 第二章 Python序列-tuple tuple创建的tips a_tuple=('a',),要这样创建,而不是a_tuple=('a'),后者是一个创建了一个字符 tup ...
- [python笔记][第二章Python序列-list]
2016/1/27学习内容 第二章 Python序列-list list常用操作 list.append(x) list.extend(L) list.insert(index,x) list.rem ...
- python变量和变量赋值的几种形式
动态类型的语言 python是动态类型的语言,不需要声明变量的类型. 实际上,python中的变量仅仅只是用来保存一个数据对象的地址.无论是什么数据对象,在内存中创建好数据对象之后,都只是把它的地址保 ...
- [Python笔记][第二章Python序列-复杂的数据结构]
2016/1/27学习内容 第二章 Python序列-复杂的数据结构 堆 import heapq #添加元素进堆 heapq.heappush(heap,n) #小根堆堆顶 heapq.heappo ...
- python学习笔记:python序列
python序列包括字符串.列表和元组三部分,下面先总的说一下python序列共有的一些操作符和内建函数. 一.python序列 序列类型操作符 标准类型的操作符一般都能适用于所有的序列类型,这里说一 ...
随机推荐
- 在C++中怎么判断一个double型数据的小数点部分是否为零
例:double sf = 123.123: 这里我们怎么判断sf小数点部分是否为零,可以直接用原数减去将sf强制转换后的整数是否为零来判断. if((sf - (int)sf) == 0),则说明s ...
- bzoj 4556 字符串
后缀数组,暴力硬跑 贼快 #include<cstdio> #include<cstring> #include<iostream> #include<alg ...
- bzoj 2002 弹飞绵羊 分块
正解lct,然而本蒟蒻并不会.... 分块思路很清晰,处理出每个点弹出所在块所需要的步数及出去后的第一个位置 #include<cstdio> #include<cstring> ...
- [ZLXOI2015]殉国 数论 扩展欧几里得
题目大意:已知a,b,c,求满足ax+by=c (x>=0,y>=0)的(x+y)最大值与最小值与解的个数. 直接exgcd,求出x,y分别为最小正整数的解,然后一算就出来啦 #inclu ...
- B20J_2243_[SDOI2011]染色_树链剖分+线段树
B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...
- BZOJ_3697_采药人的路径_点分治
BZOJ_3697_采药人的路径_点分治 Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材. 采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性 ...
- python的 a,b=b,a+b 和 a=b b=a+b 的区别(经典)
刚刚我在学习python的时候,发现下面的这个赋值要把给绕晕了(思考了很久),所以我整理之后写下博文, 希望对未来的学弟学妹有帮助! 永远爱你们的! ----新宝宝 n,a,b=0,0,1 while ...
- i春秋----Misc
好久没有写 博客今天更新多了一些 解题思路:题目做多了,自然能够想到是凯撒解密: 查看得到答案; flag{4c850c5b3b2756e67a91bad8e046dda} 2: 解题思路:是我想太多 ...
- PPT分享第01季-226套多种风格模板
包含商务欧美扁平风.唯美文艺IOS风.互联网计划书风.扁平风手绘风卡通风 .中国风等多种风格 下面是部分模板截图: 下面是下载地址
- 扒一扒.NET Core的环境配置提供程序
很久之前,在玩Docker的时候顺便扒了扒,最近,终于下定决心花了些时间整理并成文,希望能够给大家一些帮助. 目录 .NET Core中的配置 ASP.NET Core中的配置 扒一扒环境变量提供程序 ...