我用两种方法做了一些实验来初始化二维列表
我在当地的MacBookPro和Leetcode游乐场上进行了测试,结果显示第一种方法比第二种方法快4-5倍
有人能解释一下列表理解的滞后性吗
n = 999
t0 = time.time()
arr1 = [[None] * n for _ in range(n)]
t1 = time.time()
print(t1 - t0)
t2 = time.time()
arr2 = [[None for _ in range(n)] for _ in range(n)]
t3 = time.time()
print(t3 - t2)
我注意到不同的技术生成了不同的结构(正如我在一篇评论中所指出的),这种重写产生了相同的结构,但正如@juanpa arrivillaga所指出的,您实际上得到了对单个列表的多个引用,当您开始为数组元素赋值时,就会显示出来
这只是一个玩具实验,如果元素数据类型与numpy兼容,那么如果创建数组,它可以进一步加快速度
注意,您正在做两件不同的事情。您打算使用:
您已经将内部列表包装在一个额外的列表中,但这不会对计时结果产生很大影响。列表重复版本肯定更快
[None]*n
非常快,它精确地分配底层缓冲区,然后执行C级循环[None for _ in range(n)]
是一个使用append的python级循环,append是按固定时间摊销的,但会涉及缓冲区重新分配只需查看字节码就可以给出一个提示:
基本上,所有的工作都是在{}中完成的。对于列表理解:
循环工作是在Python解释器级别完成的。此外,它通过
.append
来增长列表,这在算法上是有效的,但仍然比列表重复所做的要慢,列表重复都被推到C层中以下是C源代码:
https://github.com/python/cpython/blob/48ed88a93bb0bbeaae9a4cfaa533e4edf13bcb51/Objects/listobject.c#L504
如您所见,它将底层缓冲区分配到所需的确切大小:
然后,它执行快速循环,在不重新分配的情况下填充缓冲区。最普遍的情况是:
相关问题 更多 >
编程相关推荐