1

What I mean by this is may I change the calling index of an array. For example, if I have array a = [1,2,3] can I make it so a[1] = 1? I know this is an option in FORTRAN which certainly keeps things organized and legible. Thanks

handroski
  • 81
  • 2
  • 3
  • 15
  • do you mean your array index starts at 1, instead of 0? – smushi Sep 25 '14 at 03:31
  • dictionaries are good for this, perhaps. – monkut Sep 25 '14 at 03:32
  • If you explain your circumstance and *why* you want to do this then I am sure there is a solution. In general the solution would be to subclass the `list` type, but I doubt if that is necessary – Borodin Sep 25 '14 at 03:34
  • Haha, "which certainly keeps things organized and legible". – user2864740 Sep 25 '14 at 03:35
  • I just wanted to know if there was a simple solution. other than adding a dummy element – handroski Sep 25 '14 at 03:37
  • @user2 864740: My thoughts exactly! This is *possible* in Perl, but it is documented with severe admonishments *not* to *ever* do it. – Borodin Sep 25 '14 at 03:41
  • @handroski: As I said, there probably is a simple solution, but you haven't told us the *problem* you're trying to solve by doing this. – Borodin Sep 25 '14 at 03:42
  • You can probably redefine `__getitem__` and its friends (I'm not sure if you'd really want to do that). See: http://stackoverflow.com/questions/1957780/python-overloading-the-operator-getitem-method – Yosh Sep 25 '14 at 03:47
  • You can easily make it so that a[1-1] = 1. – Wlerin Sep 25 '14 at 03:54

4 Answers4

5

Changing the indexing of a list in Python is almost definitely not what you want to do as it will break len(some_list), lead to off-by-one errors of valid input, and iteration. Starting at index[1] runs counter to most of the language's design.

Python's lists are implemented on top of C arrays (see listobject.c in the Python source), which are indexed starting at 0.

If you're positive that you need to start counting at one, consider initializing your lists by setting a[0] to None so that you're it's clear that you're inserting a dummy value.

  • 1
    Wonderful solution. Thank you – handroski Sep 25 '14 at 03:45
  • No problem. You could also create a function that returns a list with `None` prepended, but please note that `None` is falsey. –  Sep 25 '14 at 03:46
  • 2
    Note that adding a dummy value will essentially break `len(a)` as well as iteration – Peter Gibson Sep 25 '14 at 03:46
  • 1
    Oh yeah, @PeterGibson, definitely not advisable because it means reinventing a lot of functions to handle the off-by-one error that accompanying changing the C underpinnings. –  Sep 25 '14 at 03:49
  • seems to register fine using len(a). Returns empty space when called. Im wondering what will happen if I attempt to plot. – handroski Sep 25 '14 at 03:50
  • Adding your comment to my answer @PeterGibson, I should have included the warning alongside my disclaimer of "this is not what you want, but..." –  Sep 25 '14 at 03:50
  • operations on that element are a big no. This is fine for me because itll be a warning that I am off by one is my array operations. Thanks again @tristan,@Peter Gibson – handroski Sep 25 '14 at 03:56
  • @tristan: I assume the OP doesn't mean to use `mylist[1]` to access `mylist[0]`, but rather that, say, `mylist[1900]` doesn't require 1,900 wasted elements to be declared, and that `mylist.append('x')` on an ampty list assigns the value to `mylist[1900]`. I think it just needs a class. – Borodin Sep 26 '14 at 17:00
  • @Borodin I'm not going to assume what OP means -- if he decides that he actually wants a reserved-but-not-initialized list, I'll let him ask for it. –  Sep 26 '14 at 19:17
4

Although in general it is inadvisable, you are free to extend built-in types, for example:

# Python 3 syntax
class FiveList(list):
    def __getitem__(self, idx):
        return super().__getitem__(idx - 5)

>>> FiveList(range(100))[10]
5

You'd have to implement a whole lot of magic methods (below), and also check if argument is int-like (index) or a slice.

__getitem__
__setitem__
__delitem__

Also, watch out for negative indices, as those are special in Python.

Dima Tisnek
  • 11,241
  • 4
  • 68
  • 120
1

Without knowing more about your application is is difficult to help, but it may be useful for you to read Emulating Container Types.

I suggest that if you were to write a class, say BasedArray, that had an integer base attribute that specified the index of the first element, and a normal zero-based list that held the data. Then you could get away with writing just the __len__, __get item__ and __setitem__ methods, which would be trivial, and probably __iter__ which is less so. The exact set of methods you need depends on what you want to do with these based arrays once you have them.

Borodin
  • 126,100
  • 9
  • 70
  • 144
0

I assume you mean start index at 1, instead of 0?

Why not just put 0 at the start? E.g.

 [0,1,2,3]
smushi
  • 701
  • 6
  • 17