Python Forum

Full Version: rings
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
i was thinking about the concept of a new container type. this is not for any particular need i have so i have no need to implement this. the name "ring" seems to make sense. maybe someone has a better name. a ring is very much like a list.

does anyone think this might have some uses. it seems to me like practice implementing a container.

a ring is a list with the end connected back to its own beginning. indexing is modulo the len() of the ring. a ring of 8 items can be indexed at [90] and access the very same position as [2] or [-6]. as in a list, index [-1] is the last item in a ring. a ring can be empty. trying to index an empty ring raises IndexError. indexing beyond the size of the ring indexes % len(ring)

ring.pop(pos) removes and returns one item from the ring, making the ring smaller by one. pop defaults to -1.

ring.insert(item,pos) inserts item where it comes to be after position pos making the ring one larger. pos defaults to -1 which inserts between the last and first like append() for a list.

ring.insertbefore(item,pos) might be implemented.

ring.rotateforward(count) shifts items forward in the right with items in the end (at [-1]) moving into the beginning (at [0]). this is repeated count times. a negative count rotates in reverse.

ring.reverse() flips a ring over, so to speak. all items will now be in reverse order.

ring() creates an new empty ring.

ring(ring) creates a duplicate ring with the same items and references.

ring(list/tuple) creates a ring with all items and references in the same order.

ring(a,b,c,d) is like ring((a,b,c,d))

to create a ring with one container do ring((container)) or do ring([container]).

a ring used as an iterator starts at position 0 and never ends.
I would use a list and an integer as the underlying data, so that ring[k] is ring.list[(k + ring.shift) % len(ring.list)].

How would you slice a ring?
Have you seen collections.deque?
Sounds like a ring buffer to me.
it is inspired by a ring buffer. i made the fastest ring buffer in C (never copies data).
I use this concept all the time in pygame for flipping through animation frames. I just do the norm of checking for end of the list and set index to 0 after the end. But it is usually static as the animations dont change mid way.

But I would use a ring if it exists just to get rid of the code to reset the index
There are several ring buffers or circular buffers in Pypi, some of them for numpy, some as C extensions, probably some in pure python, but they all seem to be for character strings. I haven't seen a true circular list.
from collections import deque

foo = deque([1,2,3], maxlen=3)
print(foo)
foo.rotate(5)
print(foo)
foo.append(4)
print(foo)
Output:
deque([1, 2, 3], maxlen=3) deque([2, 3, 1], maxlen=3) deque([3, 1, 4], maxlen=3)
@buran If you want fast random access, a linked list such as a deque looks suboptimal. Of course, we would need some benchmarks to decide.
for random access it may be sub-optimal, but as the docs state
Quote:Deques are a generalization of stacks and queues (the name is pronounced “deck” and is short for “double-ended queue”). Deques support thread-safe, memory efficient appends and pops from either side of the deque with approximately the same O(1) performance in either direction.
I may misunderstand your point though
Pages: 1 2