Queue.__iter__ with a generator

Recall the weaknesses of using a separate iterator class:

The definition

class Queue (object):

    # Unmentioned methods identical to previous implementation

    def __iter__ (self):
        current_node = self._head
        while current_node is not None:
            item = current_node[0]
            yield item
            current_node = current_node[1]

    # We no longer require a separate QueueIterator class
The complete implementation

Weaknesses resolved

# queue is a Queue with integers in it
even_queue = Queue()
# Note: this code is for illustrative purposes. The following two lines
# are more sensibly expressed as:
# while len(queue) > 0:
#     num = queue.dequeue()
for num in queue:
    queue.dequeue()
    if num % 2 == 0:
        even_queue.enqueue(num)
    else:
        queue.enqueue(randint(0, 10))

Generators are good!

We already know that iterators are good -- they allow us to define a simple, consistent iteration pattern for our special functions or collection classes. Hopefully it is now also apparent that using generators greatly simplifies the process of defining iterators, making our code clear and simple.

itertools uses generators