- A+

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).

EDIT: let's bench this answer and Ted's answer

`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 `