如何预先分配列表列表?

时间:2011-03-18 01:27:57

标签: python

我正在使用此代码创建列表列表:

zeroArray = [0]*Np
zeroMatrix = []
for i in range(Np):
    zeroMatrix.append(zeroArray[:])

有更有效的方法吗?我希望有一些零线路的东西= [0] * Np; zeroMat = zeroArray * Np但找不到类似的东西。

4 个答案:

答案 0 :(得分:10)

也许您应该考虑使用NumPy。看起来你正在做数字工作,这正是它所做的。这是目前为止最快的,不包括import语句:

import numpy
Np = 80
zeroMatrix = numpy.zeros((Np, Np))

时间:

>python -m timeit -s "import numpy; Np = 80" "zeroMatrix = numpy.zeros((Np, Np))"
100000 loops, best of 3: 4.36 usec per loop

>python -m timeit -s "Np = 80" "zeroArray = [0]*Np" "zeroMatrix = [None] * Np" "for i in range(Np):" "  zeroMatrix[i] = zeroArray[:]"
10000 loops, best of 3: 62.5 usec per loop

>python -m timeit -s "Np = 80" "zeroMatrix = [[0] * Np for i in range (Np)]"
10000 loops, best of 3: 77.5 usec per loop

>python -m timeit -s "Np = 80" "zeroMatrix = [[0 for _ in range(Np)] for _ in range(Np)]"
1000 loops, best of 3: 474 usec per loop

答案 1 :(得分:8)

你可以这样做:

zeroMatrix = [[0] * Np for i in range(Np)]

更新:如果我们打算参加比赛,我发现(比我的计算机上的话)比Omnifarious'方法更快。这当然不会打败numpy;但这对所有学术都是正确的吗?我的意思是我们在这里谈论的是微秒。

我认为这是有效的,因为它可以避免append 避免预先分配zeroMatrix

zeroArray = [0] * Np
zeroMatrix = [zeroArray[:] for i in range(Np)]

我的测试结果:

$ python -m timeit -s "Np = 80" "zeroMatrix = [[0] * Np for i in range(Np)]"
1000 loops, best of 3: 200 usec per loop
$ python -m timeit -s "Np = 80" "zeroArray = [0] * Np" "zeroMatrix = [None] * Np" "for i in range(Np):" "    zeroMatrix[i] = zeroArray[:]"
10000 loops, best of 3: 171 usec per loop
$ python -m timeit -s "Np = 80" "zeroArray = [0] * Np" "zeroMatrix = [zeroArray[:] for i in range(Np)]"
10000 loops, best of 3: 165 usec per loop

答案 2 :(得分:5)

这可能会稍微提高效率:

zeroArray = [0]*Np
zeroMatrix = [None] * Np
for i in range(Np):
    zeroMatrix[i] = zeroArray[:]

你真正想要的东西不会以你希望的方式运作。这是因为如果您使用Np创建了列表元素的*个副本,则会获得Np对同一事物的引用。对于0这不是什么大不了的事,因为当你添加任何东西时,你只需要一个新的数字。但对于列表,您最终会得到一个矩阵,只要您更改了行的任何元素,整个列就会随之改变。

这种方式是迄今为止提到的第二快:

$ python3 -m timeit -s 'Np = 80' 'zeroArray = [0]*Np
zeroMatrix = [None] * Np
for i in range(Np):
    zeroMatrix[i] = zeroArray[:]'
10000 loops, best of 3: 72.8 usec per loop

$ python3 -m timeit -s 'Np = 80' 'zeroMatrix = [[0] * Np for i in range(Np)]'
10000 loops, best of 3: 85 usec per loop

$ python3 -m timeit -s 'Np = 80' 'zeroMatrix = [[0 for _ in range(Np)] for _ in range(Np)]'
1000 loops, best of 3: 566 usec per loop

我无法自行完成基于numpy的解决方案,因为我的系统上没有Python3的numpy包。但它的速度肯定更快。

答案 3 :(得分:1)

也许这就是你想要的?

zeroMatrix = [[0 for _ in range(Np)] for _ in range(Np)]

我不确定这是否会提供性能优势(配置文件,一如既往),但我并不知道“高效”的含义。除了避免使用list.append