Python3中两种二维数组初始化方式耗时差异大的原因是什么?
两种二维数组初始化方式的耗时差异原因
核心差异在于内层列表的生成逻辑
对于嵌套列表推导式写法:
a = 1000 b = 2000 test = [ [ 0 for i in range(a) ] for j in range(b) ]内层的
[0 for i in range(a)]是Python层面的循环迭代:每生成一个内层列表,都要遍历range(a)的a个元素,每次创建整数0并将其添加到列表中。整个过程要执行b*a次Python级别的循环操作,开销自然更大。对于
*运算符结合推导式的写法:a = 1000 b = 2000 test = [ [0] * a for i in range(b) ]内层的
[0]*a是利用Python内置的列表重复机制,这个操作在底层实现:直接为列表分配连续内存空间,然后复制0的引用(因为0是不可变对象,不存在浅拷贝风险),整个过程不需要Python层面的循环,相当于一次性完成内层列表的创建,开销远小于循环迭代。
需要注意的细节
- 只有当重复的元素是不可变对象(比如int、str、tuple)时,
*运算符的用法才是安全的。如果是可变对象(比如[[]]*a),会导致所有内层列表指向同一个对象,修改一个会影响所有,这是要避免的,但本题中用0完全没问题。 - 列表推导式本身已经比普通
for+append高效,但内层的循环和底层优化的*操作比起来,还是后者的执行效率更高,因为减少了Python解释器处理循环迭代的额外开销。
内容的提问来源于stack exchange,提问作者Kartik Hakim
相关产品推荐
相关产品推荐

