Python相当于vector :: reserve()

时间:2011-10-11 18:32:43

标签: c++ python

我正在寻找C ++ vector :: reserve()的Python等价物。我不知道列表提前有多大,但我知道它会相当大,我想避免尽可能多的限制,因为列表是在一个深层内循环中生长的。 / p>

到目前为止,我提出的唯一解决方案与vector :: reserve()习惯用法相比非常麻烦。该解决方案是使用[无] * K预先创建列表,在单独的计数器中跟踪列表的大小,根据需要将项目附加或设置到列表中,然后在完全构造后复制列表的一部分。还有其他选择吗?

3 个答案:

答案 0 :(得分:6)

std::vector类似,CPython的list已经预先分配了多于所需的元素,然后以赋予O(1)摊销附加的方式增加分配的空间。因此,我将把它留在那,直到我能通过剖析证明这确实是一个瓶颈。

编辑:您在评论中提到您已经完成了分析。在这种情况下,预先分配[None]*n可能是一个明智的事情,试图看看它是否真的是重复的重新分配是瓶颈。

如果您的数组是数字,我建议您查看NumPy

答案 1 :(得分:4)

对于它,我做了一些性能测试:

def foo(n):
  x = []
  for y in xrange(n): x.append(y)

def bar(n):
  x = [None] * n
  for y in xrange(n): x[y] = y

def baz(n):
  # This is obviously silly; we could just do range(n)
  # but this way makes for a fairer test
  x = [y for y in xrange(n)]

>>> timeit.timeit(lambda:foo(1000000), number=10)
1.761765391970215
>>> timeit.timeit(lambda:bar(1000000), number=10)
0.79829286962450396
>>> timeit.timeit(lambda:baz(1000000), number=10)
0.9904259479906159
>>> timeit.timeit(lambda:foo(10000), number=1000)
1.3354106457664443
>>> timeit.timeit(lambda:bar(10000), number=1000)
0.70596751821813086
>>> timeit.timeit(lambda:baz(10000), number=1000)
0.58049759117432131

答案 2 :(得分:3)

说白了,你可以通过以下方式创建一个预先调整大小的列表:

lst = [None] * N # where N = size of list

当然,您必须手动设置每个索引(而不是追加())并跟踪您使用的最后一个索引。

如果你应该这样做,那么另一个问题(我们的同志们已经做好了回答)。