浅析 Python3 列表操作之 * 和 *=

初学 Python 时总是会将a*=n理解为a=a*n,稍微深入后就会知道在 Python 中的不同,其中*调用__mul__ ,而*=调用__imul__ 。
对于 list 对象也支持乘法操作,截止到 Python3.7 版本,上述仍然是成立的。我们知道 list 是由 C 实现的,所以真正的底层调用肯定也是 C 的实现。观察 list 对象的 C 实现的源码我们会知道乘法*操作调用list_repeat,*=会调用list_inplace_repeat,下面分别看一下两者的 C 实现方式。
▍* 调用 list_repeat
从以上可以看出,list_repeat方法需要多少空间就申请多少空间,该操作返回的一个新的列表对象。
▍*= 调用 list_inplace_repeat
list_inplace_repeat代码中通过调用list_resize来进行扩容,并告诉它这个列表需要容纳size*n个元素。从list_resize代码来看,当allocated空间足够时,不会进行扩容操作。
新申请的空间总是比所需要的大的。如果进行 pop 等减小 list 元素数量的操作来看,实际上列表的大小也会按照相应策略进行缩减操作。
If the newsize falls lower than half the allocated size, then proceed with the realloc() to shrink the list.
--- From cpython
▍总结
*=会调用list_resize,可能会引起 list 空间扩容的情况,而且此时 list 对象占用空间会比实际 list 对象中元素占用空间大。*会按需获取申请空间大小,不会调用list_resize方法。
好好学习,天天向上!
版权声明: 本文为 InfoQ 作者【王坤祥】的原创文章。
原文链接:【http://xie.infoq.cn/article/718a9ebb2a55f8f21e6a7a824】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。











评论