Skip to content Skip to sidebar Skip to footer

How Can List[n] Point To List[0]? Getting Items Not In Sequence

I'm not sure about the term of this technique. I want to create a list where if I try to access an element outside the list range, the list would 'loop itself'. Example of the beha

Solution 1:

Creating a subclass of List would be a pretty useful way of doing this. Something like this, perhaps:

classmodList(list):

  def__getitem__(self, i):
    iflen(self) == 0:
      raise IndexError   # Or do something else if you want, like return []
    i = i % len(self)   # self.__len__() works alsoreturnsuper(modList, self).__getitem__(i)   # In Python 3, super().__getitem__(i)

If you want to do slicing, it's a little more complicated, but similar. Found this while looking through StackOverflow:

def__getitem__(self, i):
    ifisinstance(i, int):
      iflen(self) == 0:
        raise IndexError
      i = i % len(self)
      returnsuper(modList, self).__getitem__(i)   # list.__getitem__(i) works tooelifisinstance(i, slice):
      iflen(self) == 0:
        return []
      start = i.start % len(self)
      stop = i.stop % len(self)
      step = i.step
      returnsuper(modList, self).__getItem__(slice(start, stop, step))
    else:
      raise TypeError("invalid index")

Though this slice modding could give you a situation like [3:2], which will return an empty list. Basically slicing is hard and you'll need to decide how you want to implement it, but hopefully this is a start.

http://www.stackoverflow.com/questions/3911483/python-slice-how-to-i-know-the-python-slice-but-how-can-i-use-built-in-slice-ob

(Thanks @JonClements for all the suggestions in chat.)

EDIT: now we have some handlers for if you have an empty list. @wim suggests raising an error for single accesses, and returning [] for slices. Really it's up to you what you want to do but that seemed sensible to me, so that's what I've included in this answer.

EDIT EDIT: if you're using Python 2.x, I believe you also need to override __getslice__.

Solution 2:

Use the modulus operator % to "loop back" after indexing past the end of the list

>>> musical_scale = ['C', 'D', 'E', 'F', 'G', 'A', 'B']

defgetValue(x, l):
    return l[x % len(l)]

>>> getValue(0, musical_scale)
'C'>>> getValue(9, musical_scale)
'E'

Solution 3:

In case you'd like to extend the list class to handle getting and setting...

classUnsatList(list):
    def__getitem__(self, index):
        try:
            returnlist.__getitem__(self, index % len(self))
        except ZeroDivisionError:
            raise IndexError('list assignment index out of range')

    def__setitem__(self, index, value):
        try:
            returnlist.__setitem__(self, index % len(self), value)
        except ZeroDivisionError:
            raise IndexError('list assignment index out of range')


if __name__ == '__main__':
    test_list = UnsatList([1,2,3,4])
    assert test_list[0] == 1assert test_list[4] == 1assert test_list[8] == 1assert test_list[-8] == 1
    test_list[4] = 5assert test_list[0] == 5assert test_list[4] == 5assert test_list[8] == 5assert test_list[-8] == 5

Post a Comment for "How Can List[n] Point To List[0]? Getting Items Not In Sequence"