download: circularDocTest.py
class Circular(list):
    
    def __init__(self, sequence=[]):
        list.__init__(self, sequence)
        self.i = 0
            
    def set_index(self, i):
        if i >= len(self):
	    raise IndexError, "Can't set index out of range"
	else:
	    self.i = i
            
    def next(self, n=1):
        """
        >>> c = Circular([1, 2, 3, 15, 'www', 'u'])
        >>> print c.next(), c.i
        2 1

        >>> print c.next(3), c.i
        www 4
        
        """
        if self == []:
	    return None
	if n < 0:
	    return self.prev(abs(n))
        if n >= len(self):
            n = n % len(self)
        try:
            self.set_index(self.i + n)
            return self[self.i]
        except IndexError:
            self.set_index(self.i+n-len(self))
            return self[self.i]
            
    def prev(self, n=1):
        """

        En una lista circular de n elementos, avanzar 3 es lo mismo que
        retroceder n-3

        >>> c1 = Circular([1, 2, 3, 15, 'www', 'u'])
        >>> c2 = Circular(c1)
        >>> c1.next(3) == c2.prev(len(c2)-3)
        True

        >>> c1.i == c2.i
        True

        >>> c1.next(2) == c2.prev(-2)
        True

        """
        if self == []:
            return None
	if n < 0:
	    return self.next(abs(n))
        if n >= len(self):
            n = n % len(self)
        i = self.i - n
        if i >= 0:
            self.set_index(i)
        else:
            self.set_index(len(self)+i)
        return self[self.i]


if __name__ == '__main__':
    import doctest
    doctest.testmod()

Copyleft 2006 Juanjo Conti