Reputation: 161
Are there any standard library data structures for a queue that automatically requeues to the opposite end of the queue when an item is popped off the end? This feels like a common problem so I imagine that there could be a simple data structure that does this.
For example:
from collections import deque
from time import sleep
queue = deque([1, 2, 3, 4, 5, 6, 7, 8])
while True:
item = queue.pop()
queue.appendleft(item)
print(item)
sleep(5)
Is the above code actually optimal, or is there a better way to solve this problem?
Would it be better to just use a list and modify an index value each iteration of the loop to change which place in the list is accessed?
Upvotes: 0
Views: 1104
Reputation: 4418
`collections.deque' can be indexed like a list and has a rotate method.
from collections import deque
from time import sleep
queue = deque([1, 2, 3, 4, 5, 6, 7, 8])
while True:
item = queue[0]
queue.rotate(1)
print(item)
sleep(5)
Upvotes: 1
Reputation: 2104
Check out
https://docs.python.org/2/library/itertools.html#itertools.cycle
def cycle(iterable):
# cycle('ABCD') --> A B C D A B C D A B C D ...
saved = []
for element in iterable:
yield element
saved.append(element)
while saved:
for element in saved:
yield element
This should probably do what you need, and be very efficient.
Upvotes: 1
Reputation: 57155
What you're doing is called a rotation. Deque has this as a builtin: deque.rotate(n)
.
Rotate the deque n steps to the right. If n is negative, rotate to the left.
When the deque is not empty, rotating one step to the right is equivalent to
d.appendleft(d.pop())
, and rotating one step to the left is equivalent tod.append(d.popleft())
.
Usage:
>>> from collections import deque
>>> dq = deque()
>>> dq.append(4)
>>> dq.append(5)
>>> dq.append(6)
>>> dq
deque([4, 5, 6])
>>> dq.rotate()
>>> dq
deque([6, 4, 5])
>>> dq.rotate(2)
>>> dq
deque([4, 5, 6])
>>> dq.rotate(-2)
>>> dq
deque([6, 4, 5])
Upvotes: 1