Generators are essentially dynamic sequences, making their official debut in Python 2.5.

That got me to thinking: can we make a circular list with them?

Why yes, we can...

well done
``````# generic circular sequence.  See test suite below for usage.
def circular_sequence1(seq=""):
i = 0
while True:
yield seq[i]
i = (i + 1)%len(seq)

# circular sequence with ability to reset the index.  See test suite below.
def circular_sequence2(seq=""):
i = 0
while True:
comp = seq[i]
item = (yield seq[i])  # yield is a two-way gate
if item != None:       # .send(item) passes item back;
# None returned by yield otherwise
# look from current point onwards
try:
j = seq.index(item, i)
# look from beginning up to current point
except:
try:
j = seq.index(item, 0, i)
except:
raise
i = j
else:
i = (i+1) % len(seq)

# Test suite -- Demo code
print "\n" + "-"*30 + "\ncircular_sequence1"
print "-"*30
a = circular_sequence1(["Do","Re","Mi","Fa","Sol","La","Ti"])
for i in range(20):
print a.next()

print "\n" + "-"*30 + "\ncircular_sequence2"
print "-"*30
b = circular_sequence2(["Do","Re","Mi","Fa","Sol","La","Ti"])
for i in range(20):
print b.next()

print "Mi -->",
b.send("Mi")
print b.next()

print "Ti -->",
b.send("Ti")
print b.next()

print "Do -->",
b.send("Do")
print b.next()

print "Fi -->",
try:
b.send("Fi")
except ValueError, e:
print e

print "\n" + "-"*30 + "\ncircular_sequence2"
print "-"*30
c = circular_sequence2(["Larry", "Curly", "Moe", "Larry"])
for i in range(10):
print c.next()

print "Larry -->",
c.send("Larry")
print c.next()

print "Larry -->",
c.send("Larry")
print c.next()``````
3
Contributors
2
Replies
3
Views
11 Years
Discussion Span
Last Post by vegaseat

Very interesting! Thanks Jeff!

Another approach to a circular list ...

``````'''' ringbuffer_function_deque1.py
using the Python deque module as a ringbuffer
as the buffer fills up first entries are dropped
tested wth Python27 and Python33
'''

import collections

def ringbuffer_10(mylist, dq=collections.deque(maxlen=10)):
'''
mimics a ringbuffer of default length 10
you can change that to your needs
'''
for n in mylist:
dq.append(n)
return list(dq)

# testing ...
mylist = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
ringbuffer = ringbuffer_10(mylist)
print(ringbuffer)
print('-'*40)

# send more data
mylist = [22, 23, 24, 25]
ringbuffer = ringbuffer_10(mylist)
print(ringbuffer)

''' result ...
[12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
----------------------------------------
[16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
'''
``````

Edited by vegaseat

Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.