Create list of numbers mirrored around zero (python)

list, numpy, python

Solution

If you want it to be strictly mirrored around `0`, (i.e. always include 0 and the endpoints, and be perfectly symmetric about 0) you'll need a couple of steps.

First off, be aware of @NPE's comment above. Floating point math is not the same as decimal math!! This may seem beside the point, but it will bite you in certain circumstances.

There's more than one way to do this. Do you want to have all of the numbers be evenly spaced, or stick to the increment and only violate it at the endpoints?. This approach takes the latter of the two.

import numpy as np

def mirrored(maxval, inc=1):
    x = np.arange(inc, maxval, inc)
    if x[-1] != maxval:
        x = np.r_[x, maxval]
    return np.r_[-x[::-1], 0, x]

print mirrored(1, 0.3)

This yields:

[-1.  -0.9 -0.6 -0.3  0.   0.3  0.6  0.9  1. ]

If you want all of the numbers to be evenly spaced (but not the exact increment you specify), just use linspace:

import numpy as np

def mirrored2(maxval, inc=1):
    return np.linspace(-maxval, maxval, 2*maxval // inc)

print mirrored2(1, 0.3)

This yields:

[-1.  -0.6 -0.2  0.2  0.6  1. ]

Problem

I think this should be a simple question... but it's been holding me up for some time now :( I wish to create a list of numbers, centred (as it were) on zero, from an input that specifies the maximum and the increment. So, ``` max = 100 increment = 1 ``` would return ``` [-100,-99,-98,...,-1,0,1,...,99,100] ``` and ``` max = 35 increment = 0.2 ``` would return ``` [-35.0,-34.8,...,-0.2,0,0.2,...34.8,35.0] ``` If the increment doesn't divide neatly into the maximum, it needs to make a short last step (e.g. if counting to 1 in 0.3 increments, it would run `[-1.0,-0.6,-0.3,0.0,0.3,0.6,0.9,1.0]` `list(numpy.linspace())` seems to be the way to go but I seem to be having a complete mental block on how to make this work in the way described for anything but the simplest cases. Suggestions appreciated! edit: my own solution was ``` def mylist(stop,step): a = list(np.arange(0,-stop,-step))+[-stop] a.reverse() b = list(a) c = list(np.arange(0,stop,step))+[stop] d = b+c d.remove(0) e = list(d) return e ``` which is horribly clunky, even I can see. The best answer was: ``` def mirrored(maxval, inc): x = np.arange(inc, maxval, inc) if x[-1] != maxval: x = np.r_[x, maxval] return np.r_[-x[::-1], 0, x] ``` but I am going to have to google a little more to understand why that works (also not sure if I want to round... the input for the increment might be legitimately specified to more than one decimal place)

Original source