Python allows negative indexing on arrays!

Python supports indexes on arrays, and they work reasonably:

>>> [0,1,2][0]
0
>>> [0,1,2][1]
1
>>> [0,1,2][2]
2

Now, it gets strange when you use negative indexes…

>>> [0,1,2][-1]
2
>>> [0,1,2][-2]
1

As it turns out, the same is true if you create an array in Python Numeric or Scipy: you can actually use negative indexes. Behold:

>>> from scipy import *
>>> zeros(2)[-1]
0
>>> array([0,1,2])[-1]
2

As it turns out, a[-x] is mapped to a[x%len(a)] or something like it. I cannot tell whether this is a bug or was meant to be that way. Any other language supports negative indexing? Why would you want this “feature”?

Update: Thanks to all my readers, I’m now aware that this is a standard and well documented feature of Python, special thanks to Toby and Will. Thanks to didier for pointing out that Perl supports them too.

6 thoughts on “Python allows negative indexing on arrays!”

  1. An empty list raises an index exception if you try to access any location. And, yes, if there is only 1 element, then lst[0] and lst[-1] refer to the same value.

    Basically, Python’s sequence indexing gives each element two indices: a negative one and a non-negative one, i.e. i and i – n (where n is the length of the list).

    Most of the time I (and I think most other Python programmers) use the regular C-like index notation, and every once in a while use the negative index notation, mostly for accessing the last element or two of a sequence And even then, it’s usually a literal index, i.e. lst[-1] or lst[[-2], and almost never with variables, e.g.:

    >>> lst = [6, 5, 3, 2]
    >>> for i in range(len(lst)): # print lst in reverse
    … print lst[-i – 1]

    2
    3
    5
    6

  2. Negative indexing makes it easy to access the end of a list, e.g. you can write lst[-1] instead of lst[len(lst) – 1].

    It can also be used with slicing, e.g. filename[-3:] gives you the extension of the file name.

Leave a Reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax