Here's a blurb from the title page:
---- wep page excerpt
Shalabh Chaturvedi Copyright © 2004 Shalabh Chaturvedi
This book is part of a series:
Python Types and Objects
Python Attributes and Methods [you are here] ----
After playing with this for a while I get the feeling that trying to create an alternate access for the list is not the way to go. I was able to define the following methods with success...
### class Ring(list): def __init__(self,l): list.__init__(self,l) self._zero=0
def turn(self,incr=1): self._zero+=incr
def __getitem__(self,i):
if type(i)==int:
return list.__getitem__(self,(i-self._zero)%len(self))
else:
return [list.__getitem__(self,(k-self._zero)%len(self)) for k in range(i.start,i.stop,i.step)]
def __setitem__(self,i,v):
list.__setitem__(self,(i-self._zero)%len(self),v)
def __getslice__(self,i,j):
return list.__getslice__(self,(i-self._zero)%len(self),(j- self._zero)%len(self))
def __setslice__(self,i,j,v):
list.__setslice__(self,(i-self._zero)%len(self),(j- self._zero)%len(self),v)
def __repr__(self):
return repr([self[i] for i in range(len(self))])
###
..but then something like pop(3) pops the original element not the element in the 3rd position of the turned list:
### >>> l=Ring(range(10)) >>> l.turn(5) >>> print l [5, 6, 7, 8, 9, 0, 1, 2, 3, 4] >>> l.pop(3); print l [5, 6, 7, 8, 9, 0, 1, 2, 4] #I wanted the 8 to go ###
So in the absence of being able to redefine in the class the way that indices should be computed (like the way that your own cmp function can be supplied for the sort method) it seems best to use the existing structure and either access the list by passing it indices which have been remapped:
### >>> def ring_index(i): return (i-ring_zero)%ring_length
>>> l = range(10) >>> ring_length = len(l) >>> ring_zero = 3 #does a virtual shift to the right 3 elements >>> print l[ring_index(0)] 7 ###
But this will only help you look at individual entries and slices that don't go across the boundaries of the list.
Alternatively, the list class can be appended with helpers like 'turn' and 'segment' which can actually turn the "ring" and remove a piece from it without worrying about the endpoint:
### >>> class ring(list): def turn(self, incr=1): incr%=len(self) self[:] = self[incr:]+self[:incr] def segment(self, i, length, incr=1): length=min(len(self),length) if i+length>len(self): return self[i::incr]+self[(length-i)%incr:i+length-len(self):incr]
>>> l=ring(range(20)); l.turn(3); print l [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2] >>> >>> l.segment(17,5,3) #start at 17, length of 5, stride 3 [0, 3] ###
This is my first intoduction to the new class modifications...initially it seems nice to be able to wrap your methods up into a class like this rather than creating dangling functions in one's program.
/c
_______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor