现在我正在使用一个列表,并期待类似的东西:

verts = list (1000)

我应该用数组代替吗?


当前回答

你可以这样做:

verts = list(xrange(1000))

这将为您提供一个大小为1000个元素的列表,并且恰巧初始化值为0-999。由于list首先执行__len__来调整新列表的大小,因此应该相当有效。

其他回答

一个显而易见但可能并不有效的方法是

verts = [0 for x in range(1000)]

注意,这可以很容易地扩展到二维。 例如,要获得一个10x100的“数组”,你可以这样做

verts = [[0 for x in range(100)] for y in range(10)]

我首先想到的是:

verts = [None]*1000

但是你真的需要初始化它吗?

如果不了解问题领域的更多信息,就很难回答您的问题。 除非你确定你需要做更多的事情,否则python初始化列表的方法是:

verts = []

您是否真的看到了性能问题?如果有,性能瓶颈是什么? 不要试图去解决一个你没有的问题。动态地将数组填充到1000个元素的性能代价可能与您真正试图编写的程序完全无关。

数组类是有用的,如果你的列表中的东西总是一个特定的基本固定长度类型(例如char, int, float)。但是,它也不需要预初始化。

这样的:

 lst = [8 for i in range(9)]

创建一个列表,元素初始化8

但这:

lst = [0] * 7

会创建7个包含一个元素的列表吗

@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