SeaChange
SeaChange

Reputation: 161

Python data structure for auto-requeueing queue

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

Answers (3)

RootTwo
RootTwo

Reputation: 4418

deque.rotate()

`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

Tammo Heeren
Tammo Heeren

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

ggorlen
ggorlen

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 to d.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

Related Questions