How Can List[n] Point To List[0]? Getting Items Not In Sequence
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.
(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"