Python allows negative indexing on arrays!

Python supports indexes on arrays, and they work reasonably:

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

Now, it gets strange when you use negative indexes…

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

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]
>>> array([0,1,2])[-1]

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.

Published by

Daniel Lemire

A computer science professor at the University of Quebec (TELUQ).

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. 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](

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

Here is some inline `code`.

For more help see