现在我正在使用一个列表,并期待类似的东西:
verts = list (1000)
我应该用数组代替吗?
现在我正在使用一个列表,并期待类似的东西:
verts = list (1000)
我应该用数组代替吗?
当前回答
一个显而易见但可能并不有效的方法是
verts = [0 for x in range(1000)]
注意,这可以很容易地扩展到二维。 例如,要获得一个10x100的“数组”,你可以这样做
verts = [[0 for x in range(100)] for y in range(10)]
其他回答
@Steve已经很好地回答了你的问题:
verts = [None] * 1000
警告:正如@Joachim Wuttke指出的,列表必须用一个不可变元素初始化。[[]] * 1000不能像预期的那样工作,因为你会得到一个包含1000个相同列表的列表(类似于C中包含1000个指向同一列表的点的列表)。像int, str或tuple这样的不可变对象可以很好地工作。
选择
调整列表的大小很慢。以下结果并不令人惊讶:
>>> N = 10**6
>>> %timeit a = [None] * N
100 loops, best of 3: 7.41 ms per loop
>>> %timeit a = [None for x in xrange(N)]
10 loops, best of 3: 30 ms per loop
>>> %timeit a = [None for x in range(N)]
10 loops, best of 3: 67.7 ms per loop
>>> a = []
>>> %timeit for x in xrange(N): a.append(None)
10 loops, best of 3: 85.6 ms per loop
但是如果您没有非常大的列表,那么调整大小并不会非常慢。不要用单个元素(例如None)和固定长度来初始化列表以避免列表大小的调整,你应该考虑使用列表综合式并直接用正确的值填充列表。例如:
>>> %timeit a = [x**2 for x in xrange(N)]
10 loops, best of 3: 109 ms per loop
>>> def fill_list1():
"""Not too bad, but complicated code"""
a = [None] * N
for x in xrange(N):
a[x] = x**2
>>> %timeit fill_list1()
10 loops, best of 3: 126 ms per loop
>>> def fill_list2():
"""This is slow, use only for small lists"""
a = []
for x in xrange(N):
a.append(x**2)
>>> %timeit fill_list2()
10 loops, best of 3: 177 ms per loop
与numpy的比较
对于庞大的数据集,numpy或其他优化的库要快得多:
from numpy import ndarray, zeros
%timeit empty((N,))
1000000 loops, best of 3: 788 ns per loop
%timeit zeros((N,))
100 loops, best of 3: 3.56 ms per loop
我首先想到的是:
verts = [None]*1000
但是你真的需要初始化它吗?
如果不了解问题领域的更多信息,就很难回答您的问题。 除非你确定你需要做更多的事情,否则python初始化列表的方法是:
verts = []
您是否真的看到了性能问题?如果有,性能瓶颈是什么? 不要试图去解决一个你没有的问题。动态地将数组填充到1000个元素的性能代价可能与您真正试图编写的程序完全无关。
数组类是有用的,如果你的列表中的东西总是一个特定的基本固定长度类型(例如char, int, float)。但是,它也不需要预初始化。
一个显而易见但可能并不有效的方法是
verts = [0 for x in range(1000)]
注意,这可以很容易地扩展到二维。 例如,要获得一个10x100的“数组”,你可以这样做
verts = [[0 for x in range(100)] for y in range(10)]
Wanting to initalize an array of fixed size is a perfectly acceptable thing to do in any programming language; it isn't like the programmer wants to put a break statement in a while(true) loop. Believe me, especially if the elements are just going to be overwritten and not merely added/subtracted, like is the case of many dynamic programming algorithms, you don't want to mess around with append statements and checking if the element hasn't been initialized yet on the fly (that's a lot of code gents).
对象= [0 for x in range(1000)]
这将为程序员试图实现的目标工作。