# Most computationally efficient way to build a Python list with repeating and iterating numbers like [0, 0, 0, 1, 1, 1, 2, 2, 2 . . . ,32]

• A+
Category：Languages

I want to make an array that looks something like

``[0, 0, 0, 1, 1 , 1, 2, 2, 2,  . . .etc] ``

or

[4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, . . . etc]

There is something like

``segments = [i for i in range(32)]   ``

which will make

`` [ 1, 2, 3, 4, 5, . . . etc] ``

There are ways where I can call 3 separate sets of `i in range(32)` but I am looking to save computation by only calling it once.

What's the most computationally efficient and programatically elegant way of making array like

``[0, 0, 0, 1, 1 , 1, 2, 2, 2,  . . .etc] ``

Use `itertools.chain` on `itertools.repeat` iterables:

``import itertools  result = list(itertools.chain.from_iterable(itertools.repeat(i,3) for i in range(32)))  print(result) ``

result:

[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31]

This technique avoids the creation of intermediate lists and minimizes the pure python loops (one python loop total, using `map` could be possible to remove that last one, but that would require a `lambda` in that case, which adds one more function call).

``import itertools,time  n=1000000  start_time = time.time() for _ in range(n):     list(itertools.chain.from_iterable(itertools.repeat(i,3) for i in range(32)))  print("itertools",time.time() - start_time)  start_time = time.time() for _ in range(n):     [i for i in range(32) for _ in range(3)] print("flat listcomp",time.time() - start_time) ``

results:

``itertools 10.719785928726196 flat listcomp 13.869723081588745 ``

so using `itertools` instead of list comprension is around 30% faster (python 3.4, windows)

Notes:

the small number of repeats generates a lot of `itertools.repeat` calls in the inner loop, so in that case of 3 repeats, it's faster to do what NickA suggests:

``list(itertools.chain.from_iterable((i,)*3 for i in range(32))) ``

(7 seconds vs 10 in the above bench)

And `numpy` solution is even faster (around 1.5 second), if you can use `numpy`:

``import numpy as np np.arange(32).repeat(3)  # credits: liliscent  ``