《流畅的python》学习笔记之为什么高手在做增量操作时,不选择tuple,而选择list?tuple就已经输在了起跑线上?

tuple输在了哪里?

平时在用list和tuple做增量操作时,仿佛也察觉不到有啥区别,但是,当数据量变大时?差距是不是就出来?先看一下测试代码:

from time import time

a = [i for i in range(3*10**7)]
b = tuple(a)
print(f'增量操作前a的id={id(a)},b的id={id(b)}')

start=time()
a *= 2
mid=time()
b *= 2
end=time()
print(f'增量操作后a的id={id(a)},b的id={id(b)}')
print(f'列表增量操作耗时:{mid-start}')
print(f'元组增量操作耗时:{end-mid}')
print(f'列表增量的速度时元组增量的{(end-mid)/(mid-start)}')

运行结果如下:

可以看到当数据量千万级别时,列表的速度也才是元组的2.2倍左右,虽然这个差距不是很明显,但是,也证明了列表在做增量操作时确实比元组快!那么这其间的原因是什么呢??

细心的小伙伴可能已经发现,在做增量操作前后,列表a的id是没有发生变化的,而元组b的id却发生了变化!这说明了什么?了解id()函数作用的小伙伴都知道,这说明在元组b进行增量操作的时候开辟了新空间,产生了新变量!没错,这就是它慢的原因所在!“起跑”前得先”搬个家“哈哈哈

那么这其间的原因究竟是为什么呢?

加法增量操作与__add__,__iadd__(就地加法)的关系?

其实呢,一个序列对象在使用+=操作时,首先会去判断该序列有没有实现__iadd__方法,如果实现了就会去调用该方法,否则,会退而求其次的选择__add__方法。乘法增量中对__imul__和__mul__的调度顺序也是如此!

__add__和__iadd__之间的差别

__iadd__俗称“就地加法”,在进行增量操作时不会产生新的变量,直接将新的值添加在序列的末尾。而__add__就不一样了,假设对序列a进行a+=b的操作。它在操作前,会开辟一个新的地址空间,将其值赋给a,再将a的旧值拷贝到新的地址空间,之后再进行“就地加法”。一句话:__add__操作比__iadd__操作更费时!

所以,tuple会输的根本原因是?

没错,tuple会输的根本原因就是它没有__iadd__方法,只有__add__方法。(没有__iadd__的方法,也有因为tuple是不可变序列的缘故。)

tuple仅有的__add__方法

 list既有__add__方法,也有__iadd__方法

同步更新于个人博客系统:《流畅的python》学习笔记之为什么高手在做增量操作时,不选择tuple,而选择list?

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值