2

In Python I know how to create an array starting at some value a, incrementing each component thereon by some m until it reaches some value b:

array = numpy.arange(a, b, m)

However, what if I want m to change? Specifically, I want the array 1,2,...9,10,20,...90,100,200,...900,1000..

So increasing my increment by a factor of 10 every ten components. What would be the easiest way to achieve this? If I had to I could use loops and do this 'manually' but is there a nicer way?

Thomas Junk
  • 5,588
  • 2
  • 30
  • 43
Rudyard
  • 133
  • 1
  • 1
  • 7
  • Since you don't know a "nicer way" and the "manual" code is pretty short and clear, what is wrong with "manually"? – Rory Daulton Dec 23 '16 at 11:38
  • 1
    For a generic case, use the linked dup. For this special case : `(10**np.arange(4)[:,None]*np.arange(1,10)).ravel()`. – Divakar Dec 23 '16 at 11:54
  • can't answer as question was closed: here an idea: `import numpy as np; from itertools import chain; ar = np.fromiter(chain(*(range(10**n, 10*10**n, 10**n) for n in range(4))), dtype='int')`. this will create only your numpy array in memory and no other list. – hiro protagonist Dec 23 '16 at 11:59

3 Answers3

6

You could take advantage of numpy's broadcasting to achieve this in a couple of lines. You can create one array that gives you 1-9, then multiply that with an array that gives you powers of ten. You then flatten the final array to give you the list you want.

>>> a = np.arange(1,10)
>>> b = 10**np.arange(4)
>>> (b[:, np.newaxis] * a).flatten()

array([   1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   20,
     30,   40,   50,   60,   70,   80,   90,  100,  200,  300,  400,
    500,  600,  700,  800,  900, 1000, 2000, 3000, 4000, 5000, 6000,
   7000, 8000, 9000])
Andrew Guy
  • 9,310
  • 3
  • 28
  • 40
0

It's not easy to read or pretty, but here is a one-liner:

reduce(lambda x, y: x+y, [range(10**n, 10*10**n, 10**n) for n in range(4)])
fafl
  • 7,222
  • 3
  • 27
  • 50
0

I'd use an infinite generator:

def rudyard_steps(value=1, increment=1):
    while True:
        yield value
        value += increment
        if value % (10*increment) == 0:
            increment *= 10

Now to get the first 500 or so,

from itertools import islice
print(list(islice(rudyard_steps(), 500)))
RemcoGerlich
  • 30,470
  • 6
  • 61
  • 79