如何预分配列表的列表?
我正在用这段代码创建一个列表的列表:
zeroArray = [0]*Np
zeroMatrix = []
for i in range(Np):
zeroMatrix.append(zeroArray[:])
有没有更有效的方法来做到这一点?我希望能找到类似于 zeroArray = [0]*Np; zeroMat = zeroArray*Np 这样的写法,但我找不到类似的东西。
4 个回答
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包。不过可以肯定的是,它的速度快得多。
11
也许你可以考虑使用 NumPy。看起来你在做一些数字计算,而这正是它的强项。到目前为止,这是最快的,下面的代码不包括导入的那一行:
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
10
你可以这样做:
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