I was surprised to see that allocating with numpy is actually 2x slower than allocating a list:
In [4]: length = 10000
In [5]: %%timeit
...: #preallocating list
...: pre = [None] \* length
...: for i in range(length):
...: pre[i] = i
...:
346 µs ± 10.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [6]: %%timeit
...: pre = np.empty(length, dtype=int)
...: for i in range(length):
...: pre[i] = i
...:
688 µs ± 20.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)